[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
2010-10-06 12:23:22 +00:00
|
|
|
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Avi Kivity <avi@qumranet.com>
|
|
|
|
* Yaniv Kamay <yaniv@qumranet.com>
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
|
|
* the COPYING file in the top-level directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2007-07-06 09:20:49 +00:00
|
|
|
#include "irq.h"
|
2007-12-14 01:35:10 +00:00
|
|
|
#include "mmu.h"
|
2011-11-23 14:30:32 +00:00
|
|
|
#include "cpuid.h"
|
2007-06-28 18:15:57 +00:00
|
|
|
|
2007-12-16 09:02:48 +00:00
|
|
|
#include <linux/kvm_host.h>
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#include <linux/module.h>
|
2007-02-19 12:37:46 +00:00
|
|
|
#include <linux/kernel.h>
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#include <linux/mm.h>
|
|
|
|
#include <linux/highmem.h>
|
Detach sched.h from mm.h
First thing mm.h does is including sched.h solely for can_do_mlock() inline
function which has "current" dereference inside. By dealing with can_do_mlock()
mm.h can be detached from sched.h which is good. See below, why.
This patch
a) removes unconditional inclusion of sched.h from mm.h
b) makes can_do_mlock() normal function in mm/mlock.c
c) exports can_do_mlock() to not break compilation
d) adds sched.h inclusions back to files that were getting it indirectly.
e) adds less bloated headers to some files (asm/signal.h, jiffies.h) that were
getting them indirectly
Net result is:
a) mm.h users would get less code to open, read, preprocess, parse, ... if
they don't need sched.h
b) sched.h stops being dependency for significant number of files:
on x86_64 allmodconfig touching sched.h results in recompile of 4083 files,
after patch it's only 3744 (-8.3%).
Cross-compile tested on
all arm defconfigs, all mips defconfigs, all powerpc defconfigs,
alpha alpha-up
arm
i386 i386-up i386-defconfig i386-allnoconfig
ia64 ia64-up
m68k
mips
parisc parisc-up
powerpc powerpc-up
s390 s390-up
sparc sparc-up
sparc64 sparc64-up
um-x86_64
x86_64 x86_64-up x86_64-defconfig x86_64-allnoconfig
as well as my two usual configs.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-20 21:22:52 +00:00
|
|
|
#include <linux/sched.h>
|
KVM: Allow not-present guest page faults to bypass kvm
There are two classes of page faults trapped by kvm:
- host page faults, where the fault is needed to allow kvm to install
the shadow pte or update the guest accessed and dirty bits
- guest page faults, where the guest has faulted and kvm simply injects
the fault back into the guest to handle
The second class, guest page faults, is pure overhead. We can eliminate
some of it on vmx using the following evil trick:
- when we set up a shadow page table entry, if the corresponding guest pte
is not present, set up the shadow pte as not present
- if the guest pte _is_ present, mark the shadow pte as present but also
set one of the reserved bits in the shadow pte
- tell the vmx hardware not to trap faults which have the present bit clear
With this, normal page-not-present faults go directly to the guest,
bypassing kvm entirely.
Unfortunately, this trick only works on Intel hardware, as AMD lacks a
way to discriminate among page faults based on error code. It is also
a little risky since it uses reserved bits which might become unreserved
in the future, so a module parameter is provided to disable it.
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-09-16 16:58:32 +00:00
|
|
|
#include <linux/moduleparam.h>
|
2012-03-21 06:33:51 +00:00
|
|
|
#include <linux/mod_devicetable.h>
|
2015-04-29 18:36:05 +00:00
|
|
|
#include <linux/trace_events.h>
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 08:04:11 +00:00
|
|
|
#include <linux/slab.h>
|
2010-04-29 16:09:01 +00:00
|
|
|
#include <linux/tboot.h>
|
2014-03-07 19:03:13 +00:00
|
|
|
#include <linux/hrtimer.h>
|
2008-06-27 17:58:02 +00:00
|
|
|
#include "kvm_cache_regs.h"
|
2008-07-03 11:50:12 +00:00
|
|
|
#include "x86.h"
|
2007-06-28 18:15:57 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#include <asm/io.h>
|
2006-12-13 08:33:43 +00:00
|
|
|
#include <asm/desc.h>
|
2008-11-17 21:03:13 +00:00
|
|
|
#include <asm/vmx.h>
|
2008-11-17 21:03:16 +00:00
|
|
|
#include <asm/virtext.h>
|
2009-06-08 09:37:09 +00:00
|
|
|
#include <asm/mce.h>
|
2015-04-26 14:56:05 +00:00
|
|
|
#include <asm/fpu/internal.h>
|
2011-10-05 12:01:23 +00:00
|
|
|
#include <asm/perf_event.h>
|
2014-02-21 09:32:27 +00:00
|
|
|
#include <asm/debugreg.h>
|
2012-12-06 15:43:34 +00:00
|
|
|
#include <asm/kexec.h>
|
2015-02-09 21:44:07 +00:00
|
|
|
#include <asm/apic.h>
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2009-06-17 12:22:14 +00:00
|
|
|
#include "trace.h"
|
2015-06-19 13:45:05 +00:00
|
|
|
#include "pmu.h"
|
2009-06-17 12:22:14 +00:00
|
|
|
|
2008-05-13 10:23:38 +00:00
|
|
|
#define __ex(x) __kvm_handle_fault_on_reboot(x)
|
2011-05-15 14:13:12 +00:00
|
|
|
#define __ex_clear(x, reg) \
|
|
|
|
____kvm_handle_fault_on_reboot(x, "xor " reg " , " reg)
|
2008-05-13 10:23:38 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
MODULE_AUTHOR("Qumranet");
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
2012-03-21 06:33:51 +00:00
|
|
|
static const struct x86_cpu_id vmx_cpu_id[] = {
|
|
|
|
X86_FEATURE_MATCH(X86_FEATURE_VMX),
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(x86cpu, vmx_cpu_id);
|
|
|
|
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly enable_vpid = 1;
|
2009-03-23 15:39:48 +00:00
|
|
|
module_param_named(vpid, enable_vpid, bool, 0444);
|
2008-01-17 07:14:33 +00:00
|
|
|
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly flexpriority_enabled = 1;
|
2009-03-23 15:39:48 +00:00
|
|
|
module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO);
|
2008-03-24 16:15:14 +00:00
|
|
|
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly enable_ept = 1;
|
2009-03-23 15:39:48 +00:00
|
|
|
module_param_named(ept, enable_ept, bool, S_IRUGO);
|
2008-04-25 02:13:16 +00:00
|
|
|
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly enable_unrestricted_guest = 1;
|
2009-06-08 18:34:16 +00:00
|
|
|
module_param_named(unrestricted_guest,
|
|
|
|
enable_unrestricted_guest, bool, S_IRUGO);
|
|
|
|
|
2012-05-28 11:33:35 +00:00
|
|
|
static bool __read_mostly enable_ept_ad_bits = 1;
|
|
|
|
module_param_named(eptad, enable_ept_ad_bits, bool, S_IRUGO);
|
|
|
|
|
2012-06-12 17:30:18 +00:00
|
|
|
static bool __read_mostly emulate_invalid_guest_state = true;
|
2009-03-23 13:41:17 +00:00
|
|
|
module_param(emulate_invalid_guest_state, bool, S_IRUGO);
|
2008-08-17 13:39:48 +00:00
|
|
|
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly vmm_exclusive = 1;
|
2010-05-11 10:29:45 +00:00
|
|
|
module_param(vmm_exclusive, bool, S_IRUGO);
|
|
|
|
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly fasteoi = 1;
|
2011-08-30 10:56:17 +00:00
|
|
|
module_param(fasteoi, bool, S_IRUGO);
|
|
|
|
|
2013-04-11 11:25:16 +00:00
|
|
|
static bool __read_mostly enable_apicv = 1;
|
2013-04-11 11:25:12 +00:00
|
|
|
module_param(enable_apicv, bool, S_IRUGO);
|
2013-01-25 02:18:49 +00:00
|
|
|
|
2013-04-18 11:35:25 +00:00
|
|
|
static bool __read_mostly enable_shadow_vmcs = 1;
|
|
|
|
module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO);
|
2011-05-25 20:02:23 +00:00
|
|
|
/*
|
|
|
|
* If nested=1, nested virtualization is supported, i.e., guests may use
|
|
|
|
* VMX and be a hypervisor for its own guests. If nested=0, guests may not
|
|
|
|
* use VMX instructions.
|
|
|
|
*/
|
2012-01-12 23:02:18 +00:00
|
|
|
static bool __read_mostly nested = 0;
|
2011-05-25 20:02:23 +00:00
|
|
|
module_param(nested, bool, S_IRUGO);
|
|
|
|
|
2014-12-02 11:14:59 +00:00
|
|
|
static u64 __read_mostly host_xss;
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
static bool __read_mostly enable_pml = 1;
|
|
|
|
module_param_named(pml, enable_pml, bool, S_IRUGO);
|
|
|
|
|
2013-02-04 14:00:28 +00:00
|
|
|
#define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD)
|
|
|
|
#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST (X86_CR0_WP | X86_CR0_NE)
|
2009-12-06 15:21:14 +00:00
|
|
|
#define KVM_VM_CR0_ALWAYS_ON \
|
|
|
|
(KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
|
2009-12-07 10:26:18 +00:00
|
|
|
#define KVM_CR4_GUEST_OWNED_BITS \
|
|
|
|
(X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \
|
2014-10-08 00:16:21 +00:00
|
|
|
| X86_CR4_OSXMMEXCPT | X86_CR4_TSD)
|
2009-12-07 10:26:18 +00:00
|
|
|
|
2009-12-06 15:21:14 +00:00
|
|
|
#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
|
|
|
|
#define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
|
|
|
|
|
2010-04-08 15:19:35 +00:00
|
|
|
#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM))
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
#define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5
|
|
|
|
|
2009-10-09 10:03:20 +00:00
|
|
|
/*
|
|
|
|
* These 2 parameters are used to config the controls for Pause-Loop Exiting:
|
|
|
|
* ple_gap: upper bound on the amount of time between two successive
|
|
|
|
* executions of PAUSE in a loop. Also indicate if ple enabled.
|
2011-01-04 14:51:33 +00:00
|
|
|
* According to test, this time is usually smaller than 128 cycles.
|
2009-10-09 10:03:20 +00:00
|
|
|
* ple_window: upper bound on the amount of time a guest is allowed to execute
|
|
|
|
* in a PAUSE loop. Tests indicate that most spinlocks are held for
|
|
|
|
* less than 2^12 cycles
|
|
|
|
* Time is measured based on a counter that runs at the same rate as the TSC,
|
|
|
|
* refer SDM volume 3b section 21.6.13 & 22.1.3.
|
|
|
|
*/
|
2014-08-21 16:08:08 +00:00
|
|
|
#define KVM_VMX_DEFAULT_PLE_GAP 128
|
|
|
|
#define KVM_VMX_DEFAULT_PLE_WINDOW 4096
|
|
|
|
#define KVM_VMX_DEFAULT_PLE_WINDOW_GROW 2
|
|
|
|
#define KVM_VMX_DEFAULT_PLE_WINDOW_SHRINK 0
|
|
|
|
#define KVM_VMX_DEFAULT_PLE_WINDOW_MAX \
|
|
|
|
INT_MAX / KVM_VMX_DEFAULT_PLE_WINDOW_GROW
|
|
|
|
|
2009-10-09 10:03:20 +00:00
|
|
|
static int ple_gap = KVM_VMX_DEFAULT_PLE_GAP;
|
|
|
|
module_param(ple_gap, int, S_IRUGO);
|
|
|
|
|
|
|
|
static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
|
|
|
|
module_param(ple_window, int, S_IRUGO);
|
|
|
|
|
2014-08-21 16:08:08 +00:00
|
|
|
/* Default doubles per-vcpu window every exit. */
|
|
|
|
static int ple_window_grow = KVM_VMX_DEFAULT_PLE_WINDOW_GROW;
|
|
|
|
module_param(ple_window_grow, int, S_IRUGO);
|
|
|
|
|
|
|
|
/* Default resets per-vcpu window every exit to ple_window. */
|
|
|
|
static int ple_window_shrink = KVM_VMX_DEFAULT_PLE_WINDOW_SHRINK;
|
|
|
|
module_param(ple_window_shrink, int, S_IRUGO);
|
|
|
|
|
|
|
|
/* Default is to compute the maximum so we can never overflow. */
|
|
|
|
static int ple_window_actual_max = KVM_VMX_DEFAULT_PLE_WINDOW_MAX;
|
|
|
|
static int ple_window_max = KVM_VMX_DEFAULT_PLE_WINDOW_MAX;
|
|
|
|
module_param(ple_window_max, int, S_IRUGO);
|
|
|
|
|
2012-09-16 12:10:57 +00:00
|
|
|
extern const ulong vmx_return;
|
|
|
|
|
2011-10-05 12:01:22 +00:00
|
|
|
#define NR_AUTOLOAD_MSRS 8
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
#define VMCS02_POOL_SIZE 1
|
2010-04-28 13:40:38 +00:00
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
struct vmcs {
|
|
|
|
u32 revision_id;
|
|
|
|
u32 abort;
|
|
|
|
char data[0];
|
|
|
|
};
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
/*
|
|
|
|
* Track a VMCS that may be loaded on a certain CPU. If it is (cpu!=-1), also
|
|
|
|
* remember whether it was VMLAUNCHed, and maintain a linked list of all VMCSs
|
|
|
|
* loaded on this CPU (so we can clear them if the CPU goes down).
|
|
|
|
*/
|
|
|
|
struct loaded_vmcs {
|
|
|
|
struct vmcs *vmcs;
|
|
|
|
int cpu;
|
|
|
|
int launched;
|
|
|
|
struct list_head loaded_vmcss_on_cpu_link;
|
|
|
|
};
|
|
|
|
|
2009-09-07 08:14:12 +00:00
|
|
|
struct shared_msr_entry {
|
|
|
|
unsigned index;
|
|
|
|
u64 data;
|
2009-12-02 10:28:47 +00:00
|
|
|
u64 mask;
|
2009-09-07 08:14:12 +00:00
|
|
|
};
|
|
|
|
|
2011-05-25 20:03:55 +00:00
|
|
|
/*
|
|
|
|
* struct vmcs12 describes the state that our guest hypervisor (L1) keeps for a
|
|
|
|
* single nested guest (L2), hence the name vmcs12. Any VMX implementation has
|
|
|
|
* a VMCS structure, and vmcs12 is our emulated VMX's VMCS. This structure is
|
|
|
|
* stored in guest memory specified by VMPTRLD, but is opaque to the guest,
|
|
|
|
* which must access it using VMREAD/VMWRITE/VMCLEAR instructions.
|
|
|
|
* More than one of these structures may exist, if L1 runs multiple L2 guests.
|
|
|
|
* nested_vmx_run() will use the data here to build a vmcs02: a VMCS for the
|
|
|
|
* underlying hardware which will be used to run L2.
|
|
|
|
* This structure is packed to ensure that its layout is identical across
|
|
|
|
* machines (necessary for live migration).
|
|
|
|
* If there are changes in this struct, VMCS12_REVISION must be changed.
|
|
|
|
*/
|
2011-05-25 20:05:57 +00:00
|
|
|
typedef u64 natural_width;
|
2011-05-25 20:03:55 +00:00
|
|
|
struct __packed vmcs12 {
|
|
|
|
/* According to the Intel spec, a VMCS region must start with the
|
|
|
|
* following two fields. Then follow implementation-specific data.
|
|
|
|
*/
|
|
|
|
u32 revision_id;
|
|
|
|
u32 abort;
|
2011-05-25 20:05:57 +00:00
|
|
|
|
2011-05-25 20:06:59 +00:00
|
|
|
u32 launch_state; /* set to 0 by VMCLEAR, to 1 by VMLAUNCH */
|
|
|
|
u32 padding[7]; /* room for future expansion */
|
|
|
|
|
2011-05-25 20:05:57 +00:00
|
|
|
u64 io_bitmap_a;
|
|
|
|
u64 io_bitmap_b;
|
|
|
|
u64 msr_bitmap;
|
|
|
|
u64 vm_exit_msr_store_addr;
|
|
|
|
u64 vm_exit_msr_load_addr;
|
|
|
|
u64 vm_entry_msr_load_addr;
|
|
|
|
u64 tsc_offset;
|
|
|
|
u64 virtual_apic_page_addr;
|
|
|
|
u64 apic_access_addr;
|
2015-02-03 15:58:17 +00:00
|
|
|
u64 posted_intr_desc_addr;
|
2011-05-25 20:05:57 +00:00
|
|
|
u64 ept_pointer;
|
2015-02-03 15:57:51 +00:00
|
|
|
u64 eoi_exit_bitmap0;
|
|
|
|
u64 eoi_exit_bitmap1;
|
|
|
|
u64 eoi_exit_bitmap2;
|
|
|
|
u64 eoi_exit_bitmap3;
|
2014-12-04 11:11:07 +00:00
|
|
|
u64 xss_exit_bitmap;
|
2011-05-25 20:05:57 +00:00
|
|
|
u64 guest_physical_address;
|
|
|
|
u64 vmcs_link_pointer;
|
|
|
|
u64 guest_ia32_debugctl;
|
|
|
|
u64 guest_ia32_pat;
|
|
|
|
u64 guest_ia32_efer;
|
|
|
|
u64 guest_ia32_perf_global_ctrl;
|
|
|
|
u64 guest_pdptr0;
|
|
|
|
u64 guest_pdptr1;
|
|
|
|
u64 guest_pdptr2;
|
|
|
|
u64 guest_pdptr3;
|
2014-02-24 11:30:04 +00:00
|
|
|
u64 guest_bndcfgs;
|
2011-05-25 20:05:57 +00:00
|
|
|
u64 host_ia32_pat;
|
|
|
|
u64 host_ia32_efer;
|
|
|
|
u64 host_ia32_perf_global_ctrl;
|
|
|
|
u64 padding64[8]; /* room for future expansion */
|
|
|
|
/*
|
|
|
|
* To allow migration of L1 (complete with its L2 guests) between
|
|
|
|
* machines of different natural widths (32 or 64 bit), we cannot have
|
|
|
|
* unsigned long fields with no explict size. We use u64 (aliased
|
|
|
|
* natural_width) instead. Luckily, x86 is little-endian.
|
|
|
|
*/
|
|
|
|
natural_width cr0_guest_host_mask;
|
|
|
|
natural_width cr4_guest_host_mask;
|
|
|
|
natural_width cr0_read_shadow;
|
|
|
|
natural_width cr4_read_shadow;
|
|
|
|
natural_width cr3_target_value0;
|
|
|
|
natural_width cr3_target_value1;
|
|
|
|
natural_width cr3_target_value2;
|
|
|
|
natural_width cr3_target_value3;
|
|
|
|
natural_width exit_qualification;
|
|
|
|
natural_width guest_linear_address;
|
|
|
|
natural_width guest_cr0;
|
|
|
|
natural_width guest_cr3;
|
|
|
|
natural_width guest_cr4;
|
|
|
|
natural_width guest_es_base;
|
|
|
|
natural_width guest_cs_base;
|
|
|
|
natural_width guest_ss_base;
|
|
|
|
natural_width guest_ds_base;
|
|
|
|
natural_width guest_fs_base;
|
|
|
|
natural_width guest_gs_base;
|
|
|
|
natural_width guest_ldtr_base;
|
|
|
|
natural_width guest_tr_base;
|
|
|
|
natural_width guest_gdtr_base;
|
|
|
|
natural_width guest_idtr_base;
|
|
|
|
natural_width guest_dr7;
|
|
|
|
natural_width guest_rsp;
|
|
|
|
natural_width guest_rip;
|
|
|
|
natural_width guest_rflags;
|
|
|
|
natural_width guest_pending_dbg_exceptions;
|
|
|
|
natural_width guest_sysenter_esp;
|
|
|
|
natural_width guest_sysenter_eip;
|
|
|
|
natural_width host_cr0;
|
|
|
|
natural_width host_cr3;
|
|
|
|
natural_width host_cr4;
|
|
|
|
natural_width host_fs_base;
|
|
|
|
natural_width host_gs_base;
|
|
|
|
natural_width host_tr_base;
|
|
|
|
natural_width host_gdtr_base;
|
|
|
|
natural_width host_idtr_base;
|
|
|
|
natural_width host_ia32_sysenter_esp;
|
|
|
|
natural_width host_ia32_sysenter_eip;
|
|
|
|
natural_width host_rsp;
|
|
|
|
natural_width host_rip;
|
|
|
|
natural_width paddingl[8]; /* room for future expansion */
|
|
|
|
u32 pin_based_vm_exec_control;
|
|
|
|
u32 cpu_based_vm_exec_control;
|
|
|
|
u32 exception_bitmap;
|
|
|
|
u32 page_fault_error_code_mask;
|
|
|
|
u32 page_fault_error_code_match;
|
|
|
|
u32 cr3_target_count;
|
|
|
|
u32 vm_exit_controls;
|
|
|
|
u32 vm_exit_msr_store_count;
|
|
|
|
u32 vm_exit_msr_load_count;
|
|
|
|
u32 vm_entry_controls;
|
|
|
|
u32 vm_entry_msr_load_count;
|
|
|
|
u32 vm_entry_intr_info_field;
|
|
|
|
u32 vm_entry_exception_error_code;
|
|
|
|
u32 vm_entry_instruction_len;
|
|
|
|
u32 tpr_threshold;
|
|
|
|
u32 secondary_vm_exec_control;
|
|
|
|
u32 vm_instruction_error;
|
|
|
|
u32 vm_exit_reason;
|
|
|
|
u32 vm_exit_intr_info;
|
|
|
|
u32 vm_exit_intr_error_code;
|
|
|
|
u32 idt_vectoring_info_field;
|
|
|
|
u32 idt_vectoring_error_code;
|
|
|
|
u32 vm_exit_instruction_len;
|
|
|
|
u32 vmx_instruction_info;
|
|
|
|
u32 guest_es_limit;
|
|
|
|
u32 guest_cs_limit;
|
|
|
|
u32 guest_ss_limit;
|
|
|
|
u32 guest_ds_limit;
|
|
|
|
u32 guest_fs_limit;
|
|
|
|
u32 guest_gs_limit;
|
|
|
|
u32 guest_ldtr_limit;
|
|
|
|
u32 guest_tr_limit;
|
|
|
|
u32 guest_gdtr_limit;
|
|
|
|
u32 guest_idtr_limit;
|
|
|
|
u32 guest_es_ar_bytes;
|
|
|
|
u32 guest_cs_ar_bytes;
|
|
|
|
u32 guest_ss_ar_bytes;
|
|
|
|
u32 guest_ds_ar_bytes;
|
|
|
|
u32 guest_fs_ar_bytes;
|
|
|
|
u32 guest_gs_ar_bytes;
|
|
|
|
u32 guest_ldtr_ar_bytes;
|
|
|
|
u32 guest_tr_ar_bytes;
|
|
|
|
u32 guest_interruptibility_info;
|
|
|
|
u32 guest_activity_state;
|
|
|
|
u32 guest_sysenter_cs;
|
|
|
|
u32 host_ia32_sysenter_cs;
|
2013-03-13 10:31:24 +00:00
|
|
|
u32 vmx_preemption_timer_value;
|
|
|
|
u32 padding32[7]; /* room for future expansion */
|
2011-05-25 20:05:57 +00:00
|
|
|
u16 virtual_processor_id;
|
2015-02-03 15:58:17 +00:00
|
|
|
u16 posted_intr_nv;
|
2011-05-25 20:05:57 +00:00
|
|
|
u16 guest_es_selector;
|
|
|
|
u16 guest_cs_selector;
|
|
|
|
u16 guest_ss_selector;
|
|
|
|
u16 guest_ds_selector;
|
|
|
|
u16 guest_fs_selector;
|
|
|
|
u16 guest_gs_selector;
|
|
|
|
u16 guest_ldtr_selector;
|
|
|
|
u16 guest_tr_selector;
|
2015-02-03 15:57:51 +00:00
|
|
|
u16 guest_intr_status;
|
2011-05-25 20:05:57 +00:00
|
|
|
u16 host_es_selector;
|
|
|
|
u16 host_cs_selector;
|
|
|
|
u16 host_ss_selector;
|
|
|
|
u16 host_ds_selector;
|
|
|
|
u16 host_fs_selector;
|
|
|
|
u16 host_gs_selector;
|
|
|
|
u16 host_tr_selector;
|
2011-05-25 20:03:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* VMCS12_REVISION is an arbitrary id that should be changed if the content or
|
|
|
|
* layout of struct vmcs12 is changed. MSR_IA32_VMX_BASIC returns this id, and
|
|
|
|
* VMPTRLD verifies that the VMCS region that L1 is loading contains this id.
|
|
|
|
*/
|
|
|
|
#define VMCS12_REVISION 0x11e57ed0
|
|
|
|
|
|
|
|
/*
|
|
|
|
* VMCS12_SIZE is the number of bytes L1 should allocate for the VMXON region
|
|
|
|
* and any VMCS region. Although only sizeof(struct vmcs12) are used by the
|
|
|
|
* current implementation, 4K are reserved to avoid future complications.
|
|
|
|
*/
|
|
|
|
#define VMCS12_SIZE 0x1000
|
|
|
|
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
/* Used to remember the last vmcs02 used for some recently used vmcs12s */
|
|
|
|
struct vmcs02_list {
|
|
|
|
struct list_head list;
|
|
|
|
gpa_t vmptr;
|
|
|
|
struct loaded_vmcs vmcs02;
|
|
|
|
};
|
|
|
|
|
2011-05-25 20:02:54 +00:00
|
|
|
/*
|
|
|
|
* The nested_vmx structure is part of vcpu_vmx, and holds information we need
|
|
|
|
* for correct emulation of VMX (i.e., nested VMX) on this vcpu.
|
|
|
|
*/
|
|
|
|
struct nested_vmx {
|
|
|
|
/* Has the level1 guest done vmxon? */
|
|
|
|
bool vmxon;
|
2014-05-06 06:19:16 +00:00
|
|
|
gpa_t vmxon_ptr;
|
2011-05-25 20:03:55 +00:00
|
|
|
|
|
|
|
/* The guest-physical address of the current VMCS L1 keeps for L2 */
|
|
|
|
gpa_t current_vmptr;
|
|
|
|
/* The host-usable pointer to the above */
|
|
|
|
struct page *current_vmcs12_page;
|
|
|
|
struct vmcs12 *current_vmcs12;
|
2013-04-18 11:37:25 +00:00
|
|
|
struct vmcs *current_shadow_vmcs;
|
2013-04-18 11:39:25 +00:00
|
|
|
/*
|
|
|
|
* Indicates if the shadow vmcs must be updated with the
|
|
|
|
* data hold by vmcs12
|
|
|
|
*/
|
|
|
|
bool sync_shadow_vmcs;
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
|
|
|
|
/* vmcs02_list cache of VMCSs recently used to run L2 guests */
|
|
|
|
struct list_head vmcs02_pool;
|
|
|
|
int vmcs02_num;
|
2011-05-25 20:10:02 +00:00
|
|
|
u64 vmcs01_tsc_offset;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
/* L2 must run next, and mustn't decide to exit to L1. */
|
|
|
|
bool nested_run_pending;
|
2011-05-25 20:10:02 +00:00
|
|
|
/*
|
|
|
|
* Guest pages referred to in vmcs02 with host-physical pointers, so
|
|
|
|
* we must keep them pinned while L2 runs.
|
|
|
|
*/
|
|
|
|
struct page *apic_access_page;
|
2014-08-21 11:46:50 +00:00
|
|
|
struct page *virtual_apic_page;
|
2015-02-03 15:58:17 +00:00
|
|
|
struct page *pi_desc_page;
|
|
|
|
struct pi_desc *pi_desc;
|
|
|
|
bool pi_pending;
|
|
|
|
u16 posted_intr_nv;
|
2013-07-08 11:12:35 +00:00
|
|
|
u64 msr_ia32_feature_control;
|
2014-03-07 19:03:13 +00:00
|
|
|
|
|
|
|
struct hrtimer preemption_timer;
|
|
|
|
bool preemption_timer_expired;
|
2014-06-16 11:59:43 +00:00
|
|
|
|
|
|
|
/* to migrate it to L2 if VM_ENTRY_LOAD_DEBUG_CONTROLS is off */
|
|
|
|
u64 vmcs01_debugctl;
|
2015-02-03 15:56:30 +00:00
|
|
|
|
|
|
|
u32 nested_vmx_procbased_ctls_low;
|
|
|
|
u32 nested_vmx_procbased_ctls_high;
|
|
|
|
u32 nested_vmx_true_procbased_ctls_low;
|
|
|
|
u32 nested_vmx_secondary_ctls_low;
|
|
|
|
u32 nested_vmx_secondary_ctls_high;
|
|
|
|
u32 nested_vmx_pinbased_ctls_low;
|
|
|
|
u32 nested_vmx_pinbased_ctls_high;
|
|
|
|
u32 nested_vmx_exit_ctls_low;
|
|
|
|
u32 nested_vmx_exit_ctls_high;
|
|
|
|
u32 nested_vmx_true_exit_ctls_low;
|
|
|
|
u32 nested_vmx_entry_ctls_low;
|
|
|
|
u32 nested_vmx_entry_ctls_high;
|
|
|
|
u32 nested_vmx_true_entry_ctls_low;
|
|
|
|
u32 nested_vmx_misc_low;
|
|
|
|
u32 nested_vmx_misc_high;
|
|
|
|
u32 nested_vmx_ept_caps;
|
2011-05-25 20:02:54 +00:00
|
|
|
};
|
|
|
|
|
2013-04-11 11:25:12 +00:00
|
|
|
#define POSTED_INTR_ON 0
|
|
|
|
/* Posted-Interrupt Descriptor */
|
|
|
|
struct pi_desc {
|
|
|
|
u32 pir[8]; /* Posted interrupt requested */
|
|
|
|
u32 control; /* bit 0 of control is outstanding notification bit */
|
|
|
|
u32 rsvd[7];
|
|
|
|
} __aligned(64);
|
|
|
|
|
2013-04-11 11:25:15 +00:00
|
|
|
static bool pi_test_and_set_on(struct pi_desc *pi_desc)
|
|
|
|
{
|
|
|
|
return test_and_set_bit(POSTED_INTR_ON,
|
|
|
|
(unsigned long *)&pi_desc->control);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool pi_test_and_clear_on(struct pi_desc *pi_desc)
|
|
|
|
{
|
|
|
|
return test_and_clear_bit(POSTED_INTR_ON,
|
|
|
|
(unsigned long *)&pi_desc->control);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
|
|
|
|
{
|
|
|
|
return test_and_set_bit(vector, (unsigned long *)pi_desc->pir);
|
|
|
|
}
|
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
struct vcpu_vmx {
|
2007-07-27 07:16:56 +00:00
|
|
|
struct kvm_vcpu vcpu;
|
2008-07-17 15:04:30 +00:00
|
|
|
unsigned long host_rsp;
|
2007-09-10 14:27:03 +00:00
|
|
|
u8 fail;
|
2011-03-07 14:52:07 +00:00
|
|
|
bool nmi_known_unmasked;
|
2010-07-20 11:31:20 +00:00
|
|
|
u32 exit_intr_info;
|
2007-11-22 09:30:47 +00:00
|
|
|
u32 idt_vectoring_info;
|
2011-03-07 10:51:22 +00:00
|
|
|
ulong rflags;
|
2009-09-07 08:14:12 +00:00
|
|
|
struct shared_msr_entry *guest_msrs;
|
2007-07-27 12:13:10 +00:00
|
|
|
int nmsrs;
|
|
|
|
int save_nmsrs;
|
2013-04-11 11:25:10 +00:00
|
|
|
unsigned long host_idt_base;
|
2007-07-27 12:13:10 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2009-09-06 12:55:37 +00:00
|
|
|
u64 msr_host_kernel_gs_base;
|
|
|
|
u64 msr_guest_kernel_gs_base;
|
2007-07-27 12:13:10 +00:00
|
|
|
#endif
|
2013-11-25 13:37:13 +00:00
|
|
|
u32 vm_entry_controls_shadow;
|
|
|
|
u32 vm_exit_controls_shadow;
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
/*
|
|
|
|
* loaded_vmcs points to the VMCS currently used in this vcpu. For a
|
|
|
|
* non-nested (L1) guest, it always points to vmcs01. For a nested
|
|
|
|
* guest (L2), it points to a different VMCS.
|
|
|
|
*/
|
|
|
|
struct loaded_vmcs vmcs01;
|
|
|
|
struct loaded_vmcs *loaded_vmcs;
|
|
|
|
bool __launched; /* temporary, used in vmx_vcpu_run */
|
2010-04-28 13:40:38 +00:00
|
|
|
struct msr_autoload {
|
|
|
|
unsigned nr;
|
|
|
|
struct vmx_msr_entry guest[NR_AUTOLOAD_MSRS];
|
|
|
|
struct vmx_msr_entry host[NR_AUTOLOAD_MSRS];
|
|
|
|
} msr_autoload;
|
2007-07-27 12:13:10 +00:00
|
|
|
struct {
|
|
|
|
int loaded;
|
|
|
|
u16 fs_sel, gs_sel, ldt_sel;
|
2012-05-13 16:53:24 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
u16 ds_sel, es_sel;
|
|
|
|
#endif
|
2007-08-23 14:33:11 +00:00
|
|
|
int gs_ldt_reload_needed;
|
|
|
|
int fs_reload_needed;
|
2014-02-24 10:55:46 +00:00
|
|
|
u64 msr_host_bndcfgs;
|
2014-10-08 16:02:13 +00:00
|
|
|
unsigned long vmcs_host_cr4; /* May not match real cr4 */
|
2007-10-08 13:02:08 +00:00
|
|
|
} host_state;
|
2007-11-22 09:42:59 +00:00
|
|
|
struct {
|
2009-06-09 11:10:45 +00:00
|
|
|
int vm86_active;
|
2010-04-08 15:19:35 +00:00
|
|
|
ulong save_rflags;
|
2012-08-21 14:07:00 +00:00
|
|
|
struct kvm_segment segs[8];
|
|
|
|
} rmode;
|
|
|
|
struct {
|
|
|
|
u32 bitmask; /* 4 bits per segment (1 bit per field) */
|
2009-06-09 11:10:45 +00:00
|
|
|
struct kvm_save_segment {
|
|
|
|
u16 selector;
|
|
|
|
unsigned long base;
|
|
|
|
u32 limit;
|
|
|
|
u32 ar;
|
2012-08-21 14:07:00 +00:00
|
|
|
} seg[8];
|
2011-04-27 16:42:18 +00:00
|
|
|
} segment_cache;
|
2008-01-17 07:14:33 +00:00
|
|
|
int vpid;
|
2008-08-17 13:39:48 +00:00
|
|
|
bool emulation_required;
|
2008-09-26 07:30:57 +00:00
|
|
|
|
|
|
|
/* Support for vnmi-less CPUs */
|
|
|
|
int soft_vnmi_blocked;
|
|
|
|
ktime_t entry_time;
|
|
|
|
s64 vnmi_blocked_time;
|
2009-06-08 09:37:09 +00:00
|
|
|
u32 exit_reason;
|
2009-12-18 08:48:47 +00:00
|
|
|
|
|
|
|
bool rdtscp_enabled;
|
2011-05-25 20:02:54 +00:00
|
|
|
|
2013-04-11 11:25:12 +00:00
|
|
|
/* Posted interrupt descriptor */
|
|
|
|
struct pi_desc pi_desc;
|
|
|
|
|
2011-05-25 20:02:54 +00:00
|
|
|
/* Support for a guest hypervisor (nested VMX) */
|
|
|
|
struct nested_vmx nested;
|
2014-08-21 16:08:07 +00:00
|
|
|
|
|
|
|
/* Dynamic PLE window. */
|
|
|
|
int ple_window;
|
|
|
|
bool ple_window_dirty;
|
2015-01-28 02:54:28 +00:00
|
|
|
|
|
|
|
/* Support for PML */
|
|
|
|
#define PML_ENTITY_NUM 512
|
|
|
|
struct page *pml_pg;
|
2007-07-27 12:13:10 +00:00
|
|
|
};
|
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
enum segment_cache_field {
|
|
|
|
SEG_FIELD_SEL = 0,
|
|
|
|
SEG_FIELD_BASE = 1,
|
|
|
|
SEG_FIELD_LIMIT = 2,
|
|
|
|
SEG_FIELD_AR = 3,
|
|
|
|
|
|
|
|
SEG_FIELD_NR = 4
|
|
|
|
};
|
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2007-07-27 07:16:56 +00:00
|
|
|
return container_of(vcpu, struct vcpu_vmx, vcpu);
|
2007-07-27 12:13:10 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:05:57 +00:00
|
|
|
#define VMCS12_OFFSET(x) offsetof(struct vmcs12, x)
|
|
|
|
#define FIELD(number, name) [number] = VMCS12_OFFSET(name)
|
|
|
|
#define FIELD64(number, name) [number] = VMCS12_OFFSET(name), \
|
|
|
|
[number##_HIGH] = VMCS12_OFFSET(name)+4
|
|
|
|
|
2013-04-18 11:35:55 +00:00
|
|
|
|
2014-04-21 19:20:14 +00:00
|
|
|
static unsigned long shadow_read_only_fields[] = {
|
2013-04-18 11:35:55 +00:00
|
|
|
/*
|
|
|
|
* We do NOT shadow fields that are modified when L0
|
|
|
|
* traps and emulates any vmx instruction (e.g. VMPTRLD,
|
|
|
|
* VMXON...) executed by L1.
|
|
|
|
* For example, VM_INSTRUCTION_ERROR is read
|
|
|
|
* by L1 if a vmx instruction fails (part of the error path).
|
|
|
|
* Note the code assumes this logic. If for some reason
|
|
|
|
* we start shadowing these fields then we need to
|
|
|
|
* force a shadow sync when L0 emulates vmx instructions
|
|
|
|
* (e.g. force a sync if VM_INSTRUCTION_ERROR is modified
|
|
|
|
* by nested_vmx_failValid)
|
|
|
|
*/
|
|
|
|
VM_EXIT_REASON,
|
|
|
|
VM_EXIT_INTR_INFO,
|
|
|
|
VM_EXIT_INSTRUCTION_LEN,
|
|
|
|
IDT_VECTORING_INFO_FIELD,
|
|
|
|
IDT_VECTORING_ERROR_CODE,
|
|
|
|
VM_EXIT_INTR_ERROR_CODE,
|
|
|
|
EXIT_QUALIFICATION,
|
|
|
|
GUEST_LINEAR_ADDRESS,
|
|
|
|
GUEST_PHYSICAL_ADDRESS
|
|
|
|
};
|
2014-04-21 19:20:14 +00:00
|
|
|
static int max_shadow_read_only_fields =
|
2013-04-18 11:35:55 +00:00
|
|
|
ARRAY_SIZE(shadow_read_only_fields);
|
|
|
|
|
2014-04-21 19:20:14 +00:00
|
|
|
static unsigned long shadow_read_write_fields[] = {
|
2014-08-21 11:46:50 +00:00
|
|
|
TPR_THRESHOLD,
|
2013-04-18 11:35:55 +00:00
|
|
|
GUEST_RIP,
|
|
|
|
GUEST_RSP,
|
|
|
|
GUEST_CR0,
|
|
|
|
GUEST_CR3,
|
|
|
|
GUEST_CR4,
|
|
|
|
GUEST_INTERRUPTIBILITY_INFO,
|
|
|
|
GUEST_RFLAGS,
|
|
|
|
GUEST_CS_SELECTOR,
|
|
|
|
GUEST_CS_AR_BYTES,
|
|
|
|
GUEST_CS_LIMIT,
|
|
|
|
GUEST_CS_BASE,
|
|
|
|
GUEST_ES_BASE,
|
2014-02-24 11:30:04 +00:00
|
|
|
GUEST_BNDCFGS,
|
2013-04-18 11:35:55 +00:00
|
|
|
CR0_GUEST_HOST_MASK,
|
|
|
|
CR0_READ_SHADOW,
|
|
|
|
CR4_READ_SHADOW,
|
|
|
|
TSC_OFFSET,
|
|
|
|
EXCEPTION_BITMAP,
|
|
|
|
CPU_BASED_VM_EXEC_CONTROL,
|
|
|
|
VM_ENTRY_EXCEPTION_ERROR_CODE,
|
|
|
|
VM_ENTRY_INTR_INFO_FIELD,
|
|
|
|
VM_ENTRY_INSTRUCTION_LEN,
|
|
|
|
VM_ENTRY_EXCEPTION_ERROR_CODE,
|
|
|
|
HOST_FS_BASE,
|
|
|
|
HOST_GS_BASE,
|
|
|
|
HOST_FS_SELECTOR,
|
|
|
|
HOST_GS_SELECTOR
|
|
|
|
};
|
2014-04-21 19:20:14 +00:00
|
|
|
static int max_shadow_read_write_fields =
|
2013-04-18 11:35:55 +00:00
|
|
|
ARRAY_SIZE(shadow_read_write_fields);
|
|
|
|
|
2012-08-29 23:30:19 +00:00
|
|
|
static const unsigned short vmcs_field_to_offset_table[] = {
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id),
|
2015-02-03 15:58:17 +00:00
|
|
|
FIELD(POSTED_INTR_NV, posted_intr_nv),
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD(GUEST_ES_SELECTOR, guest_es_selector),
|
|
|
|
FIELD(GUEST_CS_SELECTOR, guest_cs_selector),
|
|
|
|
FIELD(GUEST_SS_SELECTOR, guest_ss_selector),
|
|
|
|
FIELD(GUEST_DS_SELECTOR, guest_ds_selector),
|
|
|
|
FIELD(GUEST_FS_SELECTOR, guest_fs_selector),
|
|
|
|
FIELD(GUEST_GS_SELECTOR, guest_gs_selector),
|
|
|
|
FIELD(GUEST_LDTR_SELECTOR, guest_ldtr_selector),
|
|
|
|
FIELD(GUEST_TR_SELECTOR, guest_tr_selector),
|
2015-02-03 15:57:51 +00:00
|
|
|
FIELD(GUEST_INTR_STATUS, guest_intr_status),
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD(HOST_ES_SELECTOR, host_es_selector),
|
|
|
|
FIELD(HOST_CS_SELECTOR, host_cs_selector),
|
|
|
|
FIELD(HOST_SS_SELECTOR, host_ss_selector),
|
|
|
|
FIELD(HOST_DS_SELECTOR, host_ds_selector),
|
|
|
|
FIELD(HOST_FS_SELECTOR, host_fs_selector),
|
|
|
|
FIELD(HOST_GS_SELECTOR, host_gs_selector),
|
|
|
|
FIELD(HOST_TR_SELECTOR, host_tr_selector),
|
|
|
|
FIELD64(IO_BITMAP_A, io_bitmap_a),
|
|
|
|
FIELD64(IO_BITMAP_B, io_bitmap_b),
|
|
|
|
FIELD64(MSR_BITMAP, msr_bitmap),
|
|
|
|
FIELD64(VM_EXIT_MSR_STORE_ADDR, vm_exit_msr_store_addr),
|
|
|
|
FIELD64(VM_EXIT_MSR_LOAD_ADDR, vm_exit_msr_load_addr),
|
|
|
|
FIELD64(VM_ENTRY_MSR_LOAD_ADDR, vm_entry_msr_load_addr),
|
|
|
|
FIELD64(TSC_OFFSET, tsc_offset),
|
|
|
|
FIELD64(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr),
|
|
|
|
FIELD64(APIC_ACCESS_ADDR, apic_access_addr),
|
2015-02-03 15:58:17 +00:00
|
|
|
FIELD64(POSTED_INTR_DESC_ADDR, posted_intr_desc_addr),
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD64(EPT_POINTER, ept_pointer),
|
2015-02-03 15:57:51 +00:00
|
|
|
FIELD64(EOI_EXIT_BITMAP0, eoi_exit_bitmap0),
|
|
|
|
FIELD64(EOI_EXIT_BITMAP1, eoi_exit_bitmap1),
|
|
|
|
FIELD64(EOI_EXIT_BITMAP2, eoi_exit_bitmap2),
|
|
|
|
FIELD64(EOI_EXIT_BITMAP3, eoi_exit_bitmap3),
|
2014-12-04 11:11:07 +00:00
|
|
|
FIELD64(XSS_EXIT_BITMAP, xss_exit_bitmap),
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD64(GUEST_PHYSICAL_ADDRESS, guest_physical_address),
|
|
|
|
FIELD64(VMCS_LINK_POINTER, vmcs_link_pointer),
|
|
|
|
FIELD64(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl),
|
|
|
|
FIELD64(GUEST_IA32_PAT, guest_ia32_pat),
|
|
|
|
FIELD64(GUEST_IA32_EFER, guest_ia32_efer),
|
|
|
|
FIELD64(GUEST_IA32_PERF_GLOBAL_CTRL, guest_ia32_perf_global_ctrl),
|
|
|
|
FIELD64(GUEST_PDPTR0, guest_pdptr0),
|
|
|
|
FIELD64(GUEST_PDPTR1, guest_pdptr1),
|
|
|
|
FIELD64(GUEST_PDPTR2, guest_pdptr2),
|
|
|
|
FIELD64(GUEST_PDPTR3, guest_pdptr3),
|
2014-02-24 11:30:04 +00:00
|
|
|
FIELD64(GUEST_BNDCFGS, guest_bndcfgs),
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD64(HOST_IA32_PAT, host_ia32_pat),
|
|
|
|
FIELD64(HOST_IA32_EFER, host_ia32_efer),
|
|
|
|
FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl),
|
|
|
|
FIELD(PIN_BASED_VM_EXEC_CONTROL, pin_based_vm_exec_control),
|
|
|
|
FIELD(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control),
|
|
|
|
FIELD(EXCEPTION_BITMAP, exception_bitmap),
|
|
|
|
FIELD(PAGE_FAULT_ERROR_CODE_MASK, page_fault_error_code_mask),
|
|
|
|
FIELD(PAGE_FAULT_ERROR_CODE_MATCH, page_fault_error_code_match),
|
|
|
|
FIELD(CR3_TARGET_COUNT, cr3_target_count),
|
|
|
|
FIELD(VM_EXIT_CONTROLS, vm_exit_controls),
|
|
|
|
FIELD(VM_EXIT_MSR_STORE_COUNT, vm_exit_msr_store_count),
|
|
|
|
FIELD(VM_EXIT_MSR_LOAD_COUNT, vm_exit_msr_load_count),
|
|
|
|
FIELD(VM_ENTRY_CONTROLS, vm_entry_controls),
|
|
|
|
FIELD(VM_ENTRY_MSR_LOAD_COUNT, vm_entry_msr_load_count),
|
|
|
|
FIELD(VM_ENTRY_INTR_INFO_FIELD, vm_entry_intr_info_field),
|
|
|
|
FIELD(VM_ENTRY_EXCEPTION_ERROR_CODE, vm_entry_exception_error_code),
|
|
|
|
FIELD(VM_ENTRY_INSTRUCTION_LEN, vm_entry_instruction_len),
|
|
|
|
FIELD(TPR_THRESHOLD, tpr_threshold),
|
|
|
|
FIELD(SECONDARY_VM_EXEC_CONTROL, secondary_vm_exec_control),
|
|
|
|
FIELD(VM_INSTRUCTION_ERROR, vm_instruction_error),
|
|
|
|
FIELD(VM_EXIT_REASON, vm_exit_reason),
|
|
|
|
FIELD(VM_EXIT_INTR_INFO, vm_exit_intr_info),
|
|
|
|
FIELD(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code),
|
|
|
|
FIELD(IDT_VECTORING_INFO_FIELD, idt_vectoring_info_field),
|
|
|
|
FIELD(IDT_VECTORING_ERROR_CODE, idt_vectoring_error_code),
|
|
|
|
FIELD(VM_EXIT_INSTRUCTION_LEN, vm_exit_instruction_len),
|
|
|
|
FIELD(VMX_INSTRUCTION_INFO, vmx_instruction_info),
|
|
|
|
FIELD(GUEST_ES_LIMIT, guest_es_limit),
|
|
|
|
FIELD(GUEST_CS_LIMIT, guest_cs_limit),
|
|
|
|
FIELD(GUEST_SS_LIMIT, guest_ss_limit),
|
|
|
|
FIELD(GUEST_DS_LIMIT, guest_ds_limit),
|
|
|
|
FIELD(GUEST_FS_LIMIT, guest_fs_limit),
|
|
|
|
FIELD(GUEST_GS_LIMIT, guest_gs_limit),
|
|
|
|
FIELD(GUEST_LDTR_LIMIT, guest_ldtr_limit),
|
|
|
|
FIELD(GUEST_TR_LIMIT, guest_tr_limit),
|
|
|
|
FIELD(GUEST_GDTR_LIMIT, guest_gdtr_limit),
|
|
|
|
FIELD(GUEST_IDTR_LIMIT, guest_idtr_limit),
|
|
|
|
FIELD(GUEST_ES_AR_BYTES, guest_es_ar_bytes),
|
|
|
|
FIELD(GUEST_CS_AR_BYTES, guest_cs_ar_bytes),
|
|
|
|
FIELD(GUEST_SS_AR_BYTES, guest_ss_ar_bytes),
|
|
|
|
FIELD(GUEST_DS_AR_BYTES, guest_ds_ar_bytes),
|
|
|
|
FIELD(GUEST_FS_AR_BYTES, guest_fs_ar_bytes),
|
|
|
|
FIELD(GUEST_GS_AR_BYTES, guest_gs_ar_bytes),
|
|
|
|
FIELD(GUEST_LDTR_AR_BYTES, guest_ldtr_ar_bytes),
|
|
|
|
FIELD(GUEST_TR_AR_BYTES, guest_tr_ar_bytes),
|
|
|
|
FIELD(GUEST_INTERRUPTIBILITY_INFO, guest_interruptibility_info),
|
|
|
|
FIELD(GUEST_ACTIVITY_STATE, guest_activity_state),
|
|
|
|
FIELD(GUEST_SYSENTER_CS, guest_sysenter_cs),
|
|
|
|
FIELD(HOST_IA32_SYSENTER_CS, host_ia32_sysenter_cs),
|
2013-03-13 10:31:24 +00:00
|
|
|
FIELD(VMX_PREEMPTION_TIMER_VALUE, vmx_preemption_timer_value),
|
2011-05-25 20:05:57 +00:00
|
|
|
FIELD(CR0_GUEST_HOST_MASK, cr0_guest_host_mask),
|
|
|
|
FIELD(CR4_GUEST_HOST_MASK, cr4_guest_host_mask),
|
|
|
|
FIELD(CR0_READ_SHADOW, cr0_read_shadow),
|
|
|
|
FIELD(CR4_READ_SHADOW, cr4_read_shadow),
|
|
|
|
FIELD(CR3_TARGET_VALUE0, cr3_target_value0),
|
|
|
|
FIELD(CR3_TARGET_VALUE1, cr3_target_value1),
|
|
|
|
FIELD(CR3_TARGET_VALUE2, cr3_target_value2),
|
|
|
|
FIELD(CR3_TARGET_VALUE3, cr3_target_value3),
|
|
|
|
FIELD(EXIT_QUALIFICATION, exit_qualification),
|
|
|
|
FIELD(GUEST_LINEAR_ADDRESS, guest_linear_address),
|
|
|
|
FIELD(GUEST_CR0, guest_cr0),
|
|
|
|
FIELD(GUEST_CR3, guest_cr3),
|
|
|
|
FIELD(GUEST_CR4, guest_cr4),
|
|
|
|
FIELD(GUEST_ES_BASE, guest_es_base),
|
|
|
|
FIELD(GUEST_CS_BASE, guest_cs_base),
|
|
|
|
FIELD(GUEST_SS_BASE, guest_ss_base),
|
|
|
|
FIELD(GUEST_DS_BASE, guest_ds_base),
|
|
|
|
FIELD(GUEST_FS_BASE, guest_fs_base),
|
|
|
|
FIELD(GUEST_GS_BASE, guest_gs_base),
|
|
|
|
FIELD(GUEST_LDTR_BASE, guest_ldtr_base),
|
|
|
|
FIELD(GUEST_TR_BASE, guest_tr_base),
|
|
|
|
FIELD(GUEST_GDTR_BASE, guest_gdtr_base),
|
|
|
|
FIELD(GUEST_IDTR_BASE, guest_idtr_base),
|
|
|
|
FIELD(GUEST_DR7, guest_dr7),
|
|
|
|
FIELD(GUEST_RSP, guest_rsp),
|
|
|
|
FIELD(GUEST_RIP, guest_rip),
|
|
|
|
FIELD(GUEST_RFLAGS, guest_rflags),
|
|
|
|
FIELD(GUEST_PENDING_DBG_EXCEPTIONS, guest_pending_dbg_exceptions),
|
|
|
|
FIELD(GUEST_SYSENTER_ESP, guest_sysenter_esp),
|
|
|
|
FIELD(GUEST_SYSENTER_EIP, guest_sysenter_eip),
|
|
|
|
FIELD(HOST_CR0, host_cr0),
|
|
|
|
FIELD(HOST_CR3, host_cr3),
|
|
|
|
FIELD(HOST_CR4, host_cr4),
|
|
|
|
FIELD(HOST_FS_BASE, host_fs_base),
|
|
|
|
FIELD(HOST_GS_BASE, host_gs_base),
|
|
|
|
FIELD(HOST_TR_BASE, host_tr_base),
|
|
|
|
FIELD(HOST_GDTR_BASE, host_gdtr_base),
|
|
|
|
FIELD(HOST_IDTR_BASE, host_idtr_base),
|
|
|
|
FIELD(HOST_IA32_SYSENTER_ESP, host_ia32_sysenter_esp),
|
|
|
|
FIELD(HOST_IA32_SYSENTER_EIP, host_ia32_sysenter_eip),
|
|
|
|
FIELD(HOST_RSP, host_rsp),
|
|
|
|
FIELD(HOST_RIP, host_rip),
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline short vmcs_field_to_offset(unsigned long field)
|
|
|
|
{
|
2014-11-04 17:31:19 +00:00
|
|
|
BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX);
|
|
|
|
|
|
|
|
if (field >= ARRAY_SIZE(vmcs_field_to_offset_table) ||
|
|
|
|
vmcs_field_to_offset_table[field] == 0)
|
|
|
|
return -ENOENT;
|
|
|
|
|
2011-05-25 20:05:57 +00:00
|
|
|
return vmcs_field_to_offset_table[field];
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:03:55 +00:00
|
|
|
static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return to_vmx(vcpu)->nested.current_vmcs12;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct page *nested_get_page(struct kvm_vcpu *vcpu, gpa_t addr)
|
|
|
|
{
|
2015-04-08 13:39:23 +00:00
|
|
|
struct page *page = kvm_vcpu_gfn_to_page(vcpu, addr >> PAGE_SHIFT);
|
2012-08-03 07:42:52 +00:00
|
|
|
if (is_error_page(page))
|
2011-05-25 20:03:55 +00:00
|
|
|
return NULL;
|
2012-08-03 07:42:52 +00:00
|
|
|
|
2011-05-25 20:03:55 +00:00
|
|
|
return page;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nested_release_page(struct page *page)
|
|
|
|
{
|
|
|
|
kvm_release_page_dirty(page);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nested_release_page_clean(struct page *page)
|
|
|
|
{
|
|
|
|
kvm_release_page_clean(page);
|
|
|
|
}
|
|
|
|
|
2013-08-05 08:07:17 +00:00
|
|
|
static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu);
|
2008-07-06 11:16:51 +00:00
|
|
|
static u64 construct_eptp(unsigned long root_hpa);
|
2010-05-11 10:29:48 +00:00
|
|
|
static void kvm_cpu_vmxon(u64 addr);
|
|
|
|
static void kvm_cpu_vmxoff(void);
|
2014-03-05 22:19:52 +00:00
|
|
|
static bool vmx_mpx_supported(void);
|
2014-12-02 11:14:58 +00:00
|
|
|
static bool vmx_xsaves_supported(void);
|
2015-07-29 09:49:59 +00:00
|
|
|
static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu);
|
2011-03-13 10:34:27 +00:00
|
|
|
static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
|
2012-05-31 11:49:22 +00:00
|
|
|
static void vmx_set_segment(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_segment *var, int seg);
|
|
|
|
static void vmx_get_segment(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_segment *var, int seg);
|
2012-12-20 14:57:45 +00:00
|
|
|
static bool guest_state_valid(struct kvm_vcpu *vcpu);
|
|
|
|
static u32 vmx_segment_access_rights(struct kvm_segment *var);
|
2013-04-11 11:25:15 +00:00
|
|
|
static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu);
|
2013-04-18 11:38:55 +00:00
|
|
|
static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
|
2013-04-18 11:38:25 +00:00
|
|
|
static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
|
2014-09-16 10:41:58 +00:00
|
|
|
static int alloc_identity_pagetable(struct kvm *kvm);
|
2007-06-20 08:20:04 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
|
|
|
|
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
/*
|
|
|
|
* We maintain a per-CPU linked-list of VMCS loaded on that CPU. This is needed
|
|
|
|
* when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it.
|
|
|
|
*/
|
|
|
|
static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
|
2010-07-26 15:32:38 +00:00
|
|
|
static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2009-02-24 19:46:19 +00:00
|
|
|
static unsigned long *vmx_io_bitmap_a;
|
|
|
|
static unsigned long *vmx_io_bitmap_b;
|
2009-02-24 20:26:47 +00:00
|
|
|
static unsigned long *vmx_msr_bitmap_legacy;
|
|
|
|
static unsigned long *vmx_msr_bitmap_longmode;
|
2013-01-25 02:18:50 +00:00
|
|
|
static unsigned long *vmx_msr_bitmap_legacy_x2apic;
|
|
|
|
static unsigned long *vmx_msr_bitmap_longmode_x2apic;
|
2015-02-03 15:49:31 +00:00
|
|
|
static unsigned long *vmx_msr_bitmap_nested;
|
2013-04-18 11:35:55 +00:00
|
|
|
static unsigned long *vmx_vmread_bitmap;
|
|
|
|
static unsigned long *vmx_vmwrite_bitmap;
|
2007-04-30 06:45:24 +00:00
|
|
|
|
2010-12-21 10:54:20 +00:00
|
|
|
static bool cpu_has_load_ia32_efer;
|
2011-10-05 12:01:22 +00:00
|
|
|
static bool cpu_has_load_perf_global_ctrl;
|
2010-12-21 10:54:20 +00:00
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);
|
|
|
|
static DEFINE_SPINLOCK(vmx_vpid_lock);
|
|
|
|
|
2007-07-29 08:07:42 +00:00
|
|
|
static struct vmcs_config {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
int size;
|
|
|
|
int order;
|
|
|
|
u32 revision_id;
|
2007-07-29 08:07:42 +00:00
|
|
|
u32 pin_based_exec_ctrl;
|
|
|
|
u32 cpu_based_exec_ctrl;
|
2007-10-29 01:40:42 +00:00
|
|
|
u32 cpu_based_2nd_exec_ctrl;
|
2007-07-29 08:07:42 +00:00
|
|
|
u32 vmexit_ctrl;
|
|
|
|
u32 vmentry_ctrl;
|
|
|
|
} vmcs_config;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2008-11-28 16:02:06 +00:00
|
|
|
static struct vmx_capability {
|
2008-04-25 02:13:16 +00:00
|
|
|
u32 ept;
|
|
|
|
u32 vpid;
|
|
|
|
} vmx_capability;
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#define VMX_SEGMENT_FIELD(seg) \
|
|
|
|
[VCPU_SREG_##seg] = { \
|
|
|
|
.selector = GUEST_##seg##_SELECTOR, \
|
|
|
|
.base = GUEST_##seg##_BASE, \
|
|
|
|
.limit = GUEST_##seg##_LIMIT, \
|
|
|
|
.ar_bytes = GUEST_##seg##_AR_BYTES, \
|
|
|
|
}
|
|
|
|
|
2012-08-29 23:30:19 +00:00
|
|
|
static const struct kvm_vmx_segment_field {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
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),
|
|
|
|
};
|
|
|
|
|
2009-09-07 08:14:12 +00:00
|
|
|
static u64 host_efer;
|
|
|
|
|
2009-05-31 19:58:47 +00:00
|
|
|
static void ept_save_pdptrs(struct kvm_vcpu *vcpu);
|
|
|
|
|
2007-04-19 11:28:44 +00:00
|
|
|
/*
|
2010-07-17 13:03:26 +00:00
|
|
|
* Keep MSR_STAR at the end, as setup_msrs() will try to optimize it
|
2007-04-19 11:28:44 +00:00
|
|
|
* away by decrementing the array size.
|
|
|
|
*/
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static const u32 vmx_msr_index[] = {
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2009-09-06 12:55:37 +00:00
|
|
|
MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#endif
|
2010-07-17 13:03:26 +00:00
|
|
|
MSR_EFER, MSR_TSC_AUX, MSR_STAR,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
};
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool is_page_fault(u32 intr_info)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
|
|
|
|
INTR_INFO_VALID_MASK)) ==
|
2008-12-15 12:52:10 +00:00
|
|
|
(INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool is_no_device(u32 intr_info)
|
2007-04-27 06:29:49 +00:00
|
|
|
{
|
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
|
|
|
|
INTR_INFO_VALID_MASK)) ==
|
2008-12-15 12:52:10 +00:00
|
|
|
(INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
|
2007-04-27 06:29:49 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool is_invalid_opcode(u32 intr_info)
|
2007-09-17 19:57:50 +00:00
|
|
|
{
|
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
|
|
|
|
INTR_INFO_VALID_MASK)) ==
|
2008-12-15 12:52:10 +00:00
|
|
|
(INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
|
2007-09-17 19:57:50 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool is_external_interrupt(u32 intr_info)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
|
|
|
|
== (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
|
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool is_machine_check(u32 intr_info)
|
2009-06-08 09:37:09 +00:00
|
|
|
{
|
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
|
|
|
|
INTR_INFO_VALID_MASK)) ==
|
|
|
|
(INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK);
|
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_msr_bitmap(void)
|
2008-03-28 05:18:56 +00:00
|
|
|
{
|
2009-04-01 07:52:31 +00:00
|
|
|
return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
|
2008-03-28 05:18:56 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_tpr_shadow(void)
|
2007-09-12 10:03:11 +00:00
|
|
|
{
|
2009-04-01 07:52:31 +00:00
|
|
|
return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
|
2007-09-12 10:03:11 +00:00
|
|
|
}
|
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
static inline bool cpu_need_tpr_shadow(struct kvm_vcpu *vcpu)
|
2007-09-12 10:03:11 +00:00
|
|
|
{
|
2015-07-29 10:05:37 +00:00
|
|
|
return cpu_has_vmx_tpr_shadow() && lapic_in_kernel(vcpu);
|
2007-09-12 10:03:11 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_secondary_exec_ctrls(void)
|
2007-10-29 01:40:42 +00:00
|
|
|
{
|
2009-04-01 07:52:31 +00:00
|
|
|
return vmcs_config.cpu_based_exec_ctrl &
|
|
|
|
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
|
2007-10-29 01:40:42 +00:00
|
|
|
}
|
|
|
|
|
2007-12-26 11:57:04 +00:00
|
|
|
static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
|
2007-10-29 01:40:42 +00:00
|
|
|
{
|
2009-04-01 07:52:31 +00:00
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:50 +00:00
|
|
|
static inline bool cpu_has_vmx_virtualize_x2apic_mode(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:49 +00:00
|
|
|
static inline bool cpu_has_vmx_apic_register_virt(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_APIC_REGISTER_VIRT;
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:51 +00:00
|
|
|
static inline bool cpu_has_vmx_virtual_intr_delivery(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
|
|
|
|
}
|
|
|
|
|
2013-04-11 11:25:12 +00:00
|
|
|
static inline bool cpu_has_vmx_posted_intr(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool cpu_has_vmx_apicv(void)
|
|
|
|
{
|
|
|
|
return cpu_has_vmx_apic_register_virt() &&
|
|
|
|
cpu_has_vmx_virtual_intr_delivery() &&
|
|
|
|
cpu_has_vmx_posted_intr();
|
|
|
|
}
|
|
|
|
|
2009-04-01 07:52:31 +00:00
|
|
|
static inline bool cpu_has_vmx_flexpriority(void)
|
|
|
|
{
|
|
|
|
return cpu_has_vmx_tpr_shadow() &&
|
|
|
|
cpu_has_vmx_virtualize_apic_accesses();
|
2007-10-29 01:40:42 +00:00
|
|
|
}
|
|
|
|
|
2009-06-11 15:07:40 +00:00
|
|
|
static inline bool cpu_has_vmx_ept_execute_only(void)
|
|
|
|
{
|
2010-03-15 09:29:09 +00:00
|
|
|
return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT;
|
2009-06-11 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool cpu_has_vmx_ept_2m_page(void)
|
|
|
|
{
|
2010-03-15 09:29:09 +00:00
|
|
|
return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT;
|
2009-06-11 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2010-01-05 11:02:29 +00:00
|
|
|
static inline bool cpu_has_vmx_ept_1g_page(void)
|
|
|
|
{
|
2010-03-15 09:29:09 +00:00
|
|
|
return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT;
|
2010-01-05 11:02:29 +00:00
|
|
|
}
|
|
|
|
|
2010-06-02 06:05:24 +00:00
|
|
|
static inline bool cpu_has_vmx_ept_4levels(void)
|
|
|
|
{
|
|
|
|
return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT;
|
|
|
|
}
|
|
|
|
|
2012-05-28 11:33:35 +00:00
|
|
|
static inline bool cpu_has_vmx_ept_ad_bits(void)
|
|
|
|
{
|
|
|
|
return vmx_capability.ept & VMX_EPT_AD_BIT;
|
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_invept_context(void)
|
2008-04-25 02:13:16 +00:00
|
|
|
{
|
2010-03-15 09:29:09 +00:00
|
|
|
return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
|
2008-04-25 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_invept_global(void)
|
2008-04-25 02:13:16 +00:00
|
|
|
{
|
2010-03-15 09:29:09 +00:00
|
|
|
return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
|
2008-04-25 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2010-06-04 00:51:39 +00:00
|
|
|
static inline bool cpu_has_vmx_invvpid_single(void)
|
|
|
|
{
|
|
|
|
return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
|
|
|
|
}
|
|
|
|
|
2010-06-07 02:32:29 +00:00
|
|
|
static inline bool cpu_has_vmx_invvpid_global(void)
|
|
|
|
{
|
|
|
|
return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
|
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_ept(void)
|
2008-04-25 02:13:16 +00:00
|
|
|
{
|
2009-04-01 07:52:31 +00:00
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_ENABLE_EPT;
|
2008-04-25 02:13:16 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_unrestricted_guest(void)
|
2009-06-08 18:34:16 +00:00
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_UNRESTRICTED_GUEST;
|
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_ple(void)
|
2009-10-09 10:03:20 +00:00
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_PAUSE_LOOP_EXITING;
|
|
|
|
}
|
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
static inline bool cpu_need_virtualize_apic_accesses(struct kvm_vcpu *vcpu)
|
2007-10-29 01:40:42 +00:00
|
|
|
{
|
2015-07-29 10:05:37 +00:00
|
|
|
return flexpriority_enabled && lapic_in_kernel(vcpu);
|
2007-10-29 01:40:42 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_vpid(void)
|
2008-01-17 07:14:33 +00:00
|
|
|
{
|
2009-04-01 07:52:31 +00:00
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_ENABLE_VPID;
|
2008-01-17 07:14:33 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_vmx_rdtscp(void)
|
2009-12-18 08:48:47 +00:00
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_RDTSCP;
|
|
|
|
}
|
|
|
|
|
2012-07-02 01:18:48 +00:00
|
|
|
static inline bool cpu_has_vmx_invpcid(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_ENABLE_INVPCID;
|
|
|
|
}
|
|
|
|
|
2010-03-15 09:29:09 +00:00
|
|
|
static inline bool cpu_has_virtual_nmis(void)
|
2008-05-15 10:23:25 +00:00
|
|
|
{
|
|
|
|
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
|
|
|
|
}
|
|
|
|
|
2010-06-30 04:25:15 +00:00
|
|
|
static inline bool cpu_has_vmx_wbinvd_exit(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_WBINVD_EXITING;
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:35:25 +00:00
|
|
|
static inline bool cpu_has_vmx_shadow_vmcs(void)
|
|
|
|
{
|
|
|
|
u64 vmx_msr;
|
|
|
|
rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
|
|
|
|
/* check if the cpu supports writing r/o exit information fields */
|
|
|
|
if (!(vmx_msr & MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_SHADOW_VMCS;
|
|
|
|
}
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
static inline bool cpu_has_vmx_pml(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
|
|
|
|
}
|
|
|
|
|
2009-04-01 07:52:31 +00:00
|
|
|
static inline bool report_flexpriority(void)
|
|
|
|
{
|
|
|
|
return flexpriority_enabled;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
static inline bool nested_cpu_has(struct vmcs12 *vmcs12, u32 bit)
|
|
|
|
{
|
|
|
|
return vmcs12->cpu_based_vm_exec_control & bit;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool nested_cpu_has2(struct vmcs12 *vmcs12, u32 bit)
|
|
|
|
{
|
|
|
|
return (vmcs12->cpu_based_vm_exec_control &
|
|
|
|
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) &&
|
|
|
|
(vmcs12->secondary_vm_exec_control & bit);
|
|
|
|
}
|
|
|
|
|
2013-08-05 08:07:20 +00:00
|
|
|
static inline bool nested_cpu_has_virtual_nmis(struct vmcs12 *vmcs12)
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
{
|
|
|
|
return vmcs12->pin_based_vm_exec_control & PIN_BASED_VIRTUAL_NMIS;
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
static inline bool nested_cpu_has_preemption_timer(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return vmcs12->pin_based_vm_exec_control &
|
|
|
|
PIN_BASED_VMX_PREEMPTION_TIMER;
|
|
|
|
}
|
|
|
|
|
2013-08-05 08:07:16 +00:00
|
|
|
static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT);
|
|
|
|
}
|
|
|
|
|
2014-12-04 11:11:07 +00:00
|
|
|
static inline bool nested_cpu_has_xsaves(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES) &&
|
|
|
|
vmx_xsaves_supported();
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:56:03 +00:00
|
|
|
static inline bool nested_cpu_has_virt_x2apic_mode(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE);
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:57:18 +00:00
|
|
|
static inline bool nested_cpu_has_apic_reg_virt(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_APIC_REGISTER_VIRT);
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:57:51 +00:00
|
|
|
static inline bool nested_cpu_has_vid(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
static inline bool nested_cpu_has_posted_intr(struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return vmcs12->pin_based_vm_exec_control & PIN_BASED_POSTED_INTR;
|
|
|
|
}
|
|
|
|
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
static inline bool is_exception(u32 intr_info)
|
|
|
|
{
|
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
|
|
|
|
== (INTR_TYPE_HARD_EXCEPTION | INTR_INFO_VALID_MASK);
|
|
|
|
}
|
|
|
|
|
2014-01-04 17:47:20 +00:00
|
|
|
static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
|
|
|
|
u32 exit_intr_info,
|
|
|
|
unsigned long exit_qualification);
|
2011-05-25 20:12:04 +00:00
|
|
|
static void nested_vmx_entry_failure(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12,
|
|
|
|
u32 reason, unsigned long qualification);
|
|
|
|
|
2007-07-30 06:31:43 +00:00
|
|
|
static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr)
|
2006-12-13 08:34:01 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
for (i = 0; i < vmx->nmsrs; ++i)
|
2009-09-07 08:14:12 +00:00
|
|
|
if (vmx_msr_index[vmx->guest_msrs[i].index] == msr)
|
2007-05-17 15:55:15 +00:00
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
static inline void __invvpid(int ext, u16 vpid, gva_t gva)
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
u64 vpid : 16;
|
|
|
|
u64 rsvd : 48;
|
|
|
|
u64 gva;
|
|
|
|
} operand = { vpid, 0, gva };
|
|
|
|
|
2008-05-13 10:23:38 +00:00
|
|
|
asm volatile (__ex(ASM_VMX_INVVPID)
|
2008-01-17 07:14:33 +00:00
|
|
|
/* CF==1 or ZF==1 --> rc = -1 */
|
|
|
|
"; ja 1f ; ud2 ; 1:"
|
|
|
|
: : "a"(&operand), "c"(ext) : "cc", "memory");
|
|
|
|
}
|
|
|
|
|
2008-04-28 04:24:45 +00:00
|
|
|
static inline void __invept(int ext, u64 eptp, gpa_t gpa)
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
u64 eptp, gpa;
|
|
|
|
} operand = {eptp, gpa};
|
|
|
|
|
2008-05-13 10:23:38 +00:00
|
|
|
asm volatile (__ex(ASM_VMX_INVEPT)
|
2008-04-28 04:24:45 +00:00
|
|
|
/* CF==1 or ZF==1 --> rc = -1 */
|
|
|
|
"; ja 1f ; ud2 ; 1:\n"
|
|
|
|
: : "a" (&operand), "c" (ext) : "cc", "memory");
|
|
|
|
}
|
|
|
|
|
2009-09-07 08:14:12 +00:00
|
|
|
static struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr)
|
2007-05-17 15:55:15 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2007-07-30 06:31:43 +00:00
|
|
|
i = __find_msr_index(vmx, msr);
|
2007-05-17 15:55:15 +00:00
|
|
|
if (i >= 0)
|
2007-07-27 12:13:10 +00:00
|
|
|
return &vmx->guest_msrs[i];
|
2007-02-09 16:38:40 +00:00
|
|
|
return NULL;
|
2006-12-13 08:34:01 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void vmcs_clear(struct vmcs *vmcs)
|
|
|
|
{
|
|
|
|
u64 phys_addr = __pa(vmcs);
|
|
|
|
u8 error;
|
|
|
|
|
2008-05-13 10:23:38 +00:00
|
|
|
asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0"
|
2010-12-21 14:51:50 +00:00
|
|
|
: "=qm"(error) : "a"(&phys_addr), "m"(phys_addr)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
: "cc", "memory");
|
|
|
|
if (error)
|
|
|
|
printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n",
|
|
|
|
vmcs, phys_addr);
|
|
|
|
}
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
static inline void loaded_vmcs_init(struct loaded_vmcs *loaded_vmcs)
|
|
|
|
{
|
|
|
|
vmcs_clear(loaded_vmcs->vmcs);
|
|
|
|
loaded_vmcs->cpu = -1;
|
|
|
|
loaded_vmcs->launched = 0;
|
|
|
|
}
|
|
|
|
|
2010-05-11 10:29:38 +00:00
|
|
|
static void vmcs_load(struct vmcs *vmcs)
|
|
|
|
{
|
|
|
|
u64 phys_addr = __pa(vmcs);
|
|
|
|
u8 error;
|
|
|
|
|
|
|
|
asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0"
|
2010-12-21 14:51:50 +00:00
|
|
|
: "=qm"(error) : "a"(&phys_addr), "m"(phys_addr)
|
2010-05-11 10:29:38 +00:00
|
|
|
: "cc", "memory");
|
|
|
|
if (error)
|
2011-05-25 20:16:40 +00:00
|
|
|
printk(KERN_ERR "kvm: vmptrld %p/%llx failed\n",
|
2010-05-11 10:29:38 +00:00
|
|
|
vmcs, phys_addr);
|
|
|
|
}
|
|
|
|
|
2015-09-09 22:38:55 +00:00
|
|
|
#ifdef CONFIG_KEXEC_CORE
|
2012-12-06 15:43:34 +00:00
|
|
|
/*
|
|
|
|
* This bitmap is used to indicate whether the vmclear
|
|
|
|
* operation is enabled on all cpus. All disabled by
|
|
|
|
* default.
|
|
|
|
*/
|
|
|
|
static cpumask_t crash_vmclear_enabled_bitmap = CPU_MASK_NONE;
|
|
|
|
|
|
|
|
static inline void crash_enable_local_vmclear(int cpu)
|
|
|
|
{
|
|
|
|
cpumask_set_cpu(cpu, &crash_vmclear_enabled_bitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void crash_disable_local_vmclear(int cpu)
|
|
|
|
{
|
|
|
|
cpumask_clear_cpu(cpu, &crash_vmclear_enabled_bitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int crash_local_vmclear_enabled(int cpu)
|
|
|
|
{
|
|
|
|
return cpumask_test_cpu(cpu, &crash_vmclear_enabled_bitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void crash_vmclear_local_loaded_vmcss(void)
|
|
|
|
{
|
|
|
|
int cpu = raw_smp_processor_id();
|
|
|
|
struct loaded_vmcs *v;
|
|
|
|
|
|
|
|
if (!crash_local_vmclear_enabled(cpu))
|
|
|
|
return;
|
|
|
|
|
|
|
|
list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu),
|
|
|
|
loaded_vmcss_on_cpu_link)
|
|
|
|
vmcs_clear(v->vmcs);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline void crash_enable_local_vmclear(int cpu) { }
|
|
|
|
static inline void crash_disable_local_vmclear(int cpu) { }
|
2015-09-09 22:38:55 +00:00
|
|
|
#endif /* CONFIG_KEXEC_CORE */
|
2012-12-06 15:43:34 +00:00
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
static void __loaded_vmcs_clear(void *arg)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
struct loaded_vmcs *loaded_vmcs = arg;
|
2007-01-06 00:36:23 +00:00
|
|
|
int cpu = raw_smp_processor_id();
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
if (loaded_vmcs->cpu != cpu)
|
|
|
|
return; /* vcpu migration can race with cpu offline */
|
|
|
|
if (per_cpu(current_vmcs, cpu) == loaded_vmcs->vmcs)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
per_cpu(current_vmcs, cpu) = NULL;
|
2012-12-06 15:43:34 +00:00
|
|
|
crash_disable_local_vmclear(cpu);
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
list_del(&loaded_vmcs->loaded_vmcss_on_cpu_link);
|
2012-11-28 12:54:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* we should ensure updating loaded_vmcs->loaded_vmcss_on_cpu_link
|
|
|
|
* is before setting loaded_vmcs->vcpu to -1 which is done in
|
|
|
|
* loaded_vmcs_init. Otherwise, other cpu can see vcpu = -1 fist
|
|
|
|
* then adds the vmcs into percpu list before it is deleted.
|
|
|
|
*/
|
|
|
|
smp_wmb();
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
loaded_vmcs_init(loaded_vmcs);
|
2012-12-06 15:43:34 +00:00
|
|
|
crash_enable_local_vmclear(cpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs)
|
2007-02-12 08:54:46 +00:00
|
|
|
{
|
2012-11-28 12:53:15 +00:00
|
|
|
int cpu = loaded_vmcs->cpu;
|
|
|
|
|
|
|
|
if (cpu != -1)
|
|
|
|
smp_call_function_single(cpu,
|
|
|
|
__loaded_vmcs_clear, loaded_vmcs, 1);
|
2007-02-12 08:54:46 +00:00
|
|
|
}
|
|
|
|
|
2010-06-07 02:33:27 +00:00
|
|
|
static inline void vpid_sync_vcpu_single(struct vcpu_vmx *vmx)
|
2008-01-17 07:14:33 +00:00
|
|
|
{
|
|
|
|
if (vmx->vpid == 0)
|
|
|
|
return;
|
|
|
|
|
2010-06-04 00:51:39 +00:00
|
|
|
if (cpu_has_vmx_invvpid_single())
|
|
|
|
__invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx->vpid, 0);
|
2008-01-17 07:14:33 +00:00
|
|
|
}
|
|
|
|
|
2010-06-07 02:32:29 +00:00
|
|
|
static inline void vpid_sync_vcpu_global(void)
|
|
|
|
{
|
|
|
|
if (cpu_has_vmx_invvpid_global())
|
|
|
|
__invvpid(VMX_VPID_EXTENT_ALL_CONTEXT, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vpid_sync_context(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
if (cpu_has_vmx_invvpid_single())
|
2010-06-07 02:33:27 +00:00
|
|
|
vpid_sync_vcpu_single(vmx);
|
2010-06-07 02:32:29 +00:00
|
|
|
else
|
|
|
|
vpid_sync_vcpu_global();
|
|
|
|
}
|
|
|
|
|
2008-04-28 04:24:45 +00:00
|
|
|
static inline void ept_sync_global(void)
|
|
|
|
{
|
|
|
|
if (cpu_has_vmx_invept_global())
|
|
|
|
__invept(VMX_EPT_EXTENT_GLOBAL, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void ept_sync_context(u64 eptp)
|
|
|
|
{
|
2009-03-23 16:26:32 +00:00
|
|
|
if (enable_ept) {
|
2008-04-28 04:24:45 +00:00
|
|
|
if (cpu_has_vmx_invept_context())
|
|
|
|
__invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0);
|
|
|
|
else
|
|
|
|
ept_sync_global();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-15 14:13:13 +00:00
|
|
|
static __always_inline unsigned long vmcs_readl(unsigned long field)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2011-05-15 14:13:12 +00:00
|
|
|
unsigned long value;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2011-05-15 14:13:12 +00:00
|
|
|
asm volatile (__ex_clear(ASM_VMX_VMREAD_RDX_RAX, "%0")
|
|
|
|
: "=a"(value) : "d"(field) : "cc");
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2011-05-15 14:13:13 +00:00
|
|
|
static __always_inline u16 vmcs_read16(unsigned long field)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
return vmcs_readl(field);
|
|
|
|
}
|
|
|
|
|
2011-05-15 14:13:13 +00:00
|
|
|
static __always_inline u32 vmcs_read32(unsigned long field)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
return vmcs_readl(field);
|
|
|
|
}
|
|
|
|
|
2011-05-15 14:13:13 +00:00
|
|
|
static __always_inline u64 vmcs_read64(unsigned long field)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return vmcs_readl(field);
|
|
|
|
#else
|
|
|
|
return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-01-06 00:36:56 +00:00
|
|
|
static noinline void vmwrite_error(unsigned long field, unsigned long value)
|
|
|
|
{
|
|
|
|
printk(KERN_ERR "vmwrite error: reg %lx value %lx (err %d)\n",
|
|
|
|
field, value, vmcs_read32(VM_INSTRUCTION_ERROR));
|
|
|
|
dump_stack();
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void vmcs_writel(unsigned long field, unsigned long value)
|
|
|
|
{
|
|
|
|
u8 error;
|
|
|
|
|
2008-05-13 10:23:38 +00:00
|
|
|
asm volatile (__ex(ASM_VMX_VMWRITE_RAX_RDX) "; setna %0"
|
2007-10-08 13:02:08 +00:00
|
|
|
: "=q"(error) : "a"(value), "d"(field) : "cc");
|
2007-01-06 00:36:56 +00:00
|
|
|
if (unlikely(error))
|
|
|
|
vmwrite_error(field, value);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmcs_write16(unsigned long field, u16 value)
|
|
|
|
{
|
|
|
|
vmcs_writel(field, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmcs_write32(unsigned long field, u32 value)
|
|
|
|
{
|
|
|
|
vmcs_writel(field, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmcs_write64(unsigned long field, u64 value)
|
|
|
|
{
|
|
|
|
vmcs_writel(field, value);
|
2008-05-12 16:25:43 +00:00
|
|
|
#ifndef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
asm volatile ("");
|
|
|
|
vmcs_writel(field+1, value >> 32);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-04-27 06:29:49 +00:00
|
|
|
static void vmcs_clear_bits(unsigned long field, u32 mask)
|
|
|
|
{
|
|
|
|
vmcs_writel(field, vmcs_readl(field) & ~mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmcs_set_bits(unsigned long field, u32 mask)
|
|
|
|
{
|
|
|
|
vmcs_writel(field, vmcs_readl(field) | mask);
|
|
|
|
}
|
|
|
|
|
2013-11-25 13:37:13 +00:00
|
|
|
static inline void vm_entry_controls_init(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
vmcs_write32(VM_ENTRY_CONTROLS, val);
|
|
|
|
vmx->vm_entry_controls_shadow = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vm_entry_controls_set(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
if (vmx->vm_entry_controls_shadow != val)
|
|
|
|
vm_entry_controls_init(vmx, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 vm_entry_controls_get(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
return vmx->vm_entry_controls_shadow;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void vm_entry_controls_setbit(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) | val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vm_entry_controls_clearbit(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) & ~val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vm_exit_controls_init(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
vmcs_write32(VM_EXIT_CONTROLS, val);
|
|
|
|
vmx->vm_exit_controls_shadow = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vm_exit_controls_set(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
if (vmx->vm_exit_controls_shadow != val)
|
|
|
|
vm_exit_controls_init(vmx, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 vm_exit_controls_get(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
return vmx->vm_exit_controls_shadow;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void vm_exit_controls_setbit(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) | val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void vm_exit_controls_clearbit(struct vcpu_vmx *vmx, u32 val)
|
|
|
|
{
|
|
|
|
vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) & ~val);
|
|
|
|
}
|
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
static void vmx_segment_cache_clear(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
vmx->segment_cache.bitmask = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool vmx_segment_cache_test_set(struct vcpu_vmx *vmx, unsigned seg,
|
|
|
|
unsigned field)
|
|
|
|
{
|
|
|
|
bool ret;
|
|
|
|
u32 mask = 1 << (seg * SEG_FIELD_NR + field);
|
|
|
|
|
|
|
|
if (!(vmx->vcpu.arch.regs_avail & (1 << VCPU_EXREG_SEGMENTS))) {
|
|
|
|
vmx->vcpu.arch.regs_avail |= (1 << VCPU_EXREG_SEGMENTS);
|
|
|
|
vmx->segment_cache.bitmask = 0;
|
|
|
|
}
|
|
|
|
ret = vmx->segment_cache.bitmask & mask;
|
|
|
|
vmx->segment_cache.bitmask |= mask;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u16 vmx_read_guest_seg_selector(struct vcpu_vmx *vmx, unsigned seg)
|
|
|
|
{
|
|
|
|
u16 *p = &vmx->segment_cache.seg[seg].selector;
|
|
|
|
|
|
|
|
if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_SEL))
|
|
|
|
*p = vmcs_read16(kvm_vmx_segment_fields[seg].selector);
|
|
|
|
return *p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ulong vmx_read_guest_seg_base(struct vcpu_vmx *vmx, unsigned seg)
|
|
|
|
{
|
|
|
|
ulong *p = &vmx->segment_cache.seg[seg].base;
|
|
|
|
|
|
|
|
if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_BASE))
|
|
|
|
*p = vmcs_readl(kvm_vmx_segment_fields[seg].base);
|
|
|
|
return *p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 vmx_read_guest_seg_limit(struct vcpu_vmx *vmx, unsigned seg)
|
|
|
|
{
|
|
|
|
u32 *p = &vmx->segment_cache.seg[seg].limit;
|
|
|
|
|
|
|
|
if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_LIMIT))
|
|
|
|
*p = vmcs_read32(kvm_vmx_segment_fields[seg].limit);
|
|
|
|
return *p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 vmx_read_guest_seg_ar(struct vcpu_vmx *vmx, unsigned seg)
|
|
|
|
{
|
|
|
|
u32 *p = &vmx->segment_cache.seg[seg].ar;
|
|
|
|
|
|
|
|
if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_AR))
|
|
|
|
*p = vmcs_read32(kvm_vmx_segment_fields[seg].ar_bytes);
|
|
|
|
return *p;
|
|
|
|
}
|
|
|
|
|
2007-05-02 14:57:40 +00:00
|
|
|
static void update_exception_bitmap(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u32 eb;
|
|
|
|
|
2010-01-20 17:20:20 +00:00
|
|
|
eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
|
|
|
|
(1u << NM_VECTOR) | (1u << DB_VECTOR);
|
|
|
|
if ((vcpu->guest_debug &
|
|
|
|
(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
|
|
|
|
(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
|
|
|
|
eb |= 1u << BP_VECTOR;
|
2009-06-09 11:10:45 +00:00
|
|
|
if (to_vmx(vcpu)->rmode.vm86_active)
|
2007-05-02 14:57:40 +00:00
|
|
|
eb = ~0;
|
2009-03-23 16:26:32 +00:00
|
|
|
if (enable_ept)
|
2008-04-28 04:24:45 +00:00
|
|
|
eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
|
2009-12-30 10:40:26 +00:00
|
|
|
if (vcpu->fpu_active)
|
|
|
|
eb &= ~(1u << NM_VECTOR);
|
KVM: nVMX: Further fixes for lazy FPU loading
KVM's "Lazy FPU loading" means that sometimes L0 needs to set CR0.TS, even
if a guest didn't set it. Moreover, L0 must also trap CR0.TS changes and
NM exceptions, even if we have a guest hypervisor (L1) who didn't want these
traps. And of course, conversely: If L1 wanted to trap these events, we
must let it, even if L0 is not interested in them.
This patch fixes some existing KVM code (in update_exception_bitmap(),
vmx_fpu_activate(), vmx_fpu_deactivate()) to do the correct merging of L0's
and L1's needs. Note that handle_cr() was already fixed in the above patch,
and that new code in introduced in previous patches already handles CR0
correctly (see prepare_vmcs02(), prepare_vmcs12(), and nested_vmx_vmexit()).
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:15:08 +00:00
|
|
|
|
|
|
|
/* When we are running a nested L2 guest and L1 specified for it a
|
|
|
|
* certain exception bitmap, we must trap the same exceptions and pass
|
|
|
|
* them to L1. When running L2, we will only handle the exceptions
|
|
|
|
* specified above if L1 did not want them.
|
|
|
|
*/
|
|
|
|
if (is_guest_mode(vcpu))
|
|
|
|
eb |= get_vmcs12(vcpu)->exception_bitmap;
|
|
|
|
|
2007-05-02 14:57:40 +00:00
|
|
|
vmcs_write32(EXCEPTION_BITMAP, eb);
|
|
|
|
}
|
|
|
|
|
2013-11-25 13:37:13 +00:00
|
|
|
static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx,
|
|
|
|
unsigned long entry, unsigned long exit)
|
2011-10-05 12:01:22 +00:00
|
|
|
{
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_clearbit(vmx, entry);
|
|
|
|
vm_exit_controls_clearbit(vmx, exit);
|
2011-10-05 12:01:22 +00:00
|
|
|
}
|
|
|
|
|
2010-04-28 13:40:38 +00:00
|
|
|
static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
struct msr_autoload *m = &vmx->msr_autoload;
|
|
|
|
|
2011-10-05 12:01:22 +00:00
|
|
|
switch (msr) {
|
|
|
|
case MSR_EFER:
|
|
|
|
if (cpu_has_load_ia32_efer) {
|
2013-11-25 13:37:13 +00:00
|
|
|
clear_atomic_switch_msr_special(vmx,
|
|
|
|
VM_ENTRY_LOAD_IA32_EFER,
|
2011-10-05 12:01:22 +00:00
|
|
|
VM_EXIT_LOAD_IA32_EFER);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MSR_CORE_PERF_GLOBAL_CTRL:
|
|
|
|
if (cpu_has_load_perf_global_ctrl) {
|
2013-11-25 13:37:13 +00:00
|
|
|
clear_atomic_switch_msr_special(vmx,
|
2011-10-05 12:01:22 +00:00
|
|
|
VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
|
|
|
|
VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2010-12-21 10:54:20 +00:00
|
|
|
}
|
|
|
|
|
2010-04-28 13:40:38 +00:00
|
|
|
for (i = 0; i < m->nr; ++i)
|
|
|
|
if (m->guest[i].index == msr)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (i == m->nr)
|
|
|
|
return;
|
|
|
|
--m->nr;
|
|
|
|
m->guest[i] = m->guest[m->nr];
|
|
|
|
m->host[i] = m->host[m->nr];
|
|
|
|
vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->nr);
|
|
|
|
vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
|
|
|
|
}
|
|
|
|
|
2013-11-25 13:37:13 +00:00
|
|
|
static void add_atomic_switch_msr_special(struct vcpu_vmx *vmx,
|
|
|
|
unsigned long entry, unsigned long exit,
|
|
|
|
unsigned long guest_val_vmcs, unsigned long host_val_vmcs,
|
|
|
|
u64 guest_val, u64 host_val)
|
2011-10-05 12:01:22 +00:00
|
|
|
{
|
|
|
|
vmcs_write64(guest_val_vmcs, guest_val);
|
|
|
|
vmcs_write64(host_val_vmcs, host_val);
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_setbit(vmx, entry);
|
|
|
|
vm_exit_controls_setbit(vmx, exit);
|
2011-10-05 12:01:22 +00:00
|
|
|
}
|
|
|
|
|
2010-04-28 13:40:38 +00:00
|
|
|
static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
|
|
|
|
u64 guest_val, u64 host_val)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
struct msr_autoload *m = &vmx->msr_autoload;
|
|
|
|
|
2011-10-05 12:01:22 +00:00
|
|
|
switch (msr) {
|
|
|
|
case MSR_EFER:
|
|
|
|
if (cpu_has_load_ia32_efer) {
|
2013-11-25 13:37:13 +00:00
|
|
|
add_atomic_switch_msr_special(vmx,
|
|
|
|
VM_ENTRY_LOAD_IA32_EFER,
|
2011-10-05 12:01:22 +00:00
|
|
|
VM_EXIT_LOAD_IA32_EFER,
|
|
|
|
GUEST_IA32_EFER,
|
|
|
|
HOST_IA32_EFER,
|
|
|
|
guest_val, host_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MSR_CORE_PERF_GLOBAL_CTRL:
|
|
|
|
if (cpu_has_load_perf_global_ctrl) {
|
2013-11-25 13:37:13 +00:00
|
|
|
add_atomic_switch_msr_special(vmx,
|
2011-10-05 12:01:22 +00:00
|
|
|
VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
|
|
|
|
VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL,
|
|
|
|
GUEST_IA32_PERF_GLOBAL_CTRL,
|
|
|
|
HOST_IA32_PERF_GLOBAL_CTRL,
|
|
|
|
guest_val, host_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2010-12-21 10:54:20 +00:00
|
|
|
}
|
|
|
|
|
2010-04-28 13:40:38 +00:00
|
|
|
for (i = 0; i < m->nr; ++i)
|
|
|
|
if (m->guest[i].index == msr)
|
|
|
|
break;
|
|
|
|
|
2011-10-05 12:01:24 +00:00
|
|
|
if (i == NR_AUTOLOAD_MSRS) {
|
2013-10-30 22:34:56 +00:00
|
|
|
printk_once(KERN_WARNING "Not enough msr switch entries. "
|
2011-10-05 12:01:24 +00:00
|
|
|
"Can't add msr %x\n", msr);
|
|
|
|
return;
|
|
|
|
} else if (i == m->nr) {
|
2010-04-28 13:40:38 +00:00
|
|
|
++m->nr;
|
|
|
|
vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->nr);
|
|
|
|
vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
|
|
|
|
}
|
|
|
|
|
|
|
|
m->guest[i].index = msr;
|
|
|
|
m->guest[i].value = guest_val;
|
|
|
|
m->host[i].index = msr;
|
|
|
|
m->host[i].value = host_val;
|
|
|
|
}
|
|
|
|
|
2007-05-02 13:54:03 +00:00
|
|
|
static void reload_tss(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* VT restores TR but not its size. Useless.
|
|
|
|
*/
|
x86: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-17 17:30:40 +00:00
|
|
|
struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
|
2008-02-20 15:57:21 +00:00
|
|
|
struct desc_struct *descs;
|
2007-05-02 13:54:03 +00:00
|
|
|
|
2010-07-26 15:32:39 +00:00
|
|
|
descs = (void *)gdt->address;
|
2007-05-02 13:54:03 +00:00
|
|
|
descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
|
|
|
|
load_TR_desc();
|
|
|
|
}
|
|
|
|
|
2009-10-29 09:00:16 +00:00
|
|
|
static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
|
2007-05-21 04:28:09 +00:00
|
|
|
{
|
2009-08-04 09:08:45 +00:00
|
|
|
u64 guest_efer;
|
2007-08-29 00:48:05 +00:00
|
|
|
u64 ignore_bits;
|
|
|
|
|
2010-01-21 13:31:50 +00:00
|
|
|
guest_efer = vmx->vcpu.arch.efer;
|
2009-08-04 09:08:45 +00:00
|
|
|
|
2007-08-29 00:48:05 +00:00
|
|
|
/*
|
2012-06-28 07:16:19 +00:00
|
|
|
* NX is emulated; LMA and LME handled by hardware; SCE meaningless
|
2007-08-29 00:48:05 +00:00
|
|
|
* outside long mode
|
|
|
|
*/
|
|
|
|
ignore_bits = EFER_NX | EFER_SCE;
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
ignore_bits |= EFER_LMA | EFER_LME;
|
|
|
|
/* SCE is meaningful only in long mode on Intel */
|
|
|
|
if (guest_efer & EFER_LMA)
|
|
|
|
ignore_bits &= ~(u64)EFER_SCE;
|
|
|
|
#endif
|
|
|
|
guest_efer &= ~ignore_bits;
|
|
|
|
guest_efer |= host_efer & ignore_bits;
|
2009-09-07 08:14:12 +00:00
|
|
|
vmx->guest_msrs[efer_offset].data = guest_efer;
|
2009-12-02 10:28:47 +00:00
|
|
|
vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
|
2010-04-28 13:42:29 +00:00
|
|
|
|
|
|
|
clear_atomic_switch_msr(vmx, MSR_EFER);
|
x86, kvm, vmx: Always use LOAD_IA32_EFER if available
At least on Sandy Bridge, letting the CPU switch IA32_EFER is much
faster than switching it manually.
I benchmarked this using the vmexit kvm-unit-test (single run, but
GOAL multiplied by 5 to do more iterations):
Test Before After Change
cpuid 2000 1932 -3.40%
vmcall 1914 1817 -5.07%
mov_from_cr8 13 13 0.00%
mov_to_cr8 19 19 0.00%
inl_from_pmtimer 19164 10619 -44.59%
inl_from_qemu 15662 10302 -34.22%
inl_from_kernel 3916 3802 -2.91%
outl_to_kernel 2230 2194 -1.61%
mov_dr 172 176 2.33%
ipi (skipped) (skipped)
ipi+halt (skipped) (skipped)
ple-round-robin 13 13 0.00%
wr_tsc_adjust_msr 1920 1845 -3.91%
rd_tsc_adjust_msr 1892 1814 -4.12%
mmio-no-eventfd:pci-mem 16394 11165 -31.90%
mmio-wildcard-eventfd:pci-mem 4607 4645 0.82%
mmio-datamatch-eventfd:pci-mem 4601 4610 0.20%
portio-no-eventfd:pci-io 11507 7942 -30.98%
portio-wildcard-eventfd:pci-io 2239 2225 -0.63%
portio-datamatch-eventfd:pci-io 2250 2234 -0.71%
I haven't explicitly computed the significance of these numbers,
but this isn't subtle.
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
[The results were reproducible on all of Nehalem, Sandy Bridge and
Ivy Bridge. The slowness of manual switching is because writing
to EFER with WRMSR triggers a TLB flush, even if the only bit you're
touching is SCE (so the page table format is not affected). Doing
the write as part of vmentry/vmexit, instead, does not flush the TLB,
probably because all processors that have EPT also have VPID. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-08 02:25:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* On EPT, we can't emulate NX, so we must switch EFER atomically.
|
|
|
|
* On CPUs that support "load IA32_EFER", always switch EFER
|
|
|
|
* atomically, since it's faster than switching it manually.
|
|
|
|
*/
|
|
|
|
if (cpu_has_load_ia32_efer ||
|
|
|
|
(enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) {
|
2010-04-28 13:42:29 +00:00
|
|
|
guest_efer = vmx->vcpu.arch.efer;
|
|
|
|
if (!(guest_efer & EFER_LMA))
|
|
|
|
guest_efer &= ~EFER_LME;
|
2014-11-10 19:19:15 +00:00
|
|
|
if (guest_efer != host_efer)
|
|
|
|
add_atomic_switch_msr(vmx, MSR_EFER,
|
|
|
|
guest_efer, host_efer);
|
2010-04-28 13:42:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-09-07 08:14:12 +00:00
|
|
|
return true;
|
2007-08-29 00:48:05 +00:00
|
|
|
}
|
|
|
|
|
2010-02-25 10:43:09 +00:00
|
|
|
static unsigned long segment_base(u16 selector)
|
|
|
|
{
|
x86: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-17 17:30:40 +00:00
|
|
|
struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
|
2010-02-25 10:43:09 +00:00
|
|
|
struct desc_struct *d;
|
|
|
|
unsigned long table_base;
|
|
|
|
unsigned long v;
|
|
|
|
|
|
|
|
if (!(selector & ~3))
|
|
|
|
return 0;
|
|
|
|
|
2010-07-26 15:32:39 +00:00
|
|
|
table_base = gdt->address;
|
2010-02-25 10:43:09 +00:00
|
|
|
|
|
|
|
if (selector & 4) { /* from ldt */
|
|
|
|
u16 ldt_selector = kvm_read_ldt();
|
|
|
|
|
|
|
|
if (!(ldt_selector & ~3))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
table_base = segment_base(ldt_selector);
|
|
|
|
}
|
|
|
|
d = (struct desc_struct *)(table_base + (selector & ~7));
|
|
|
|
v = get_desc_base(d);
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
|
|
|
|
v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
|
|
|
|
#endif
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned long kvm_read_tr_base(void)
|
|
|
|
{
|
|
|
|
u16 tr;
|
|
|
|
asm("str %0" : "=g"(tr));
|
|
|
|
return segment_base(tr);
|
|
|
|
}
|
|
|
|
|
2007-09-10 15:10:54 +00:00
|
|
|
static void vmx_save_host_state(struct kvm_vcpu *vcpu)
|
2007-05-02 13:54:03 +00:00
|
|
|
{
|
2007-09-10 15:10:54 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-09-07 08:14:12 +00:00
|
|
|
int i;
|
2007-09-10 15:10:54 +00:00
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
if (vmx->host_state.loaded)
|
2007-05-02 13:54:03 +00:00
|
|
|
return;
|
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
vmx->host_state.loaded = 1;
|
2007-05-02 13:54:03 +00:00
|
|
|
/*
|
|
|
|
* Set host fs and gs selectors. Unfortunately, 22.2.3 does not
|
|
|
|
* allow segment selectors with cpl > 0 or ti == 1.
|
|
|
|
*/
|
2008-07-10 13:53:33 +00:00
|
|
|
vmx->host_state.ldt_sel = kvm_read_ldt();
|
2007-08-23 14:33:11 +00:00
|
|
|
vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
|
2010-10-19 14:46:55 +00:00
|
|
|
savesegment(fs, vmx->host_state.fs_sel);
|
2007-08-23 14:33:11 +00:00
|
|
|
if (!(vmx->host_state.fs_sel & 7)) {
|
2007-07-27 12:13:10 +00:00
|
|
|
vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
|
2007-08-23 14:33:11 +00:00
|
|
|
vmx->host_state.fs_reload_needed = 0;
|
|
|
|
} else {
|
2007-05-02 13:54:03 +00:00
|
|
|
vmcs_write16(HOST_FS_SELECTOR, 0);
|
2007-08-23 14:33:11 +00:00
|
|
|
vmx->host_state.fs_reload_needed = 1;
|
2007-05-02 13:54:03 +00:00
|
|
|
}
|
2010-10-19 14:46:55 +00:00
|
|
|
savesegment(gs, vmx->host_state.gs_sel);
|
2007-07-27 12:13:10 +00:00
|
|
|
if (!(vmx->host_state.gs_sel & 7))
|
|
|
|
vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
|
2007-05-02 13:54:03 +00:00
|
|
|
else {
|
|
|
|
vmcs_write16(HOST_GS_SELECTOR, 0);
|
2007-08-23 14:33:11 +00:00
|
|
|
vmx->host_state.gs_ldt_reload_needed = 1;
|
2007-05-02 13:54:03 +00:00
|
|
|
}
|
|
|
|
|
2012-05-13 16:53:24 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
savesegment(ds, vmx->host_state.ds_sel);
|
|
|
|
savesegment(es, vmx->host_state.es_sel);
|
|
|
|
#endif
|
|
|
|
|
2007-05-02 13:54:03 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE));
|
|
|
|
vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE));
|
|
|
|
#else
|
2007-07-27 12:13:10 +00:00
|
|
|
vmcs_writel(HOST_FS_BASE, segment_base(vmx->host_state.fs_sel));
|
|
|
|
vmcs_writel(HOST_GS_BASE, segment_base(vmx->host_state.gs_sel));
|
2007-05-02 13:54:03 +00:00
|
|
|
#endif
|
2007-05-02 14:33:43 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_X86_64
|
2010-11-11 10:37:26 +00:00
|
|
|
rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
|
|
|
|
if (is_long_mode(&vmx->vcpu))
|
2009-09-06 12:55:37 +00:00
|
|
|
wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
|
2007-05-02 14:33:43 +00:00
|
|
|
#endif
|
2014-02-24 10:55:46 +00:00
|
|
|
if (boot_cpu_has(X86_FEATURE_MPX))
|
|
|
|
rdmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
|
2009-09-07 08:14:12 +00:00
|
|
|
for (i = 0; i < vmx->save_nmsrs; ++i)
|
|
|
|
kvm_set_shared_msr(vmx->guest_msrs[i].index,
|
2009-12-02 10:28:47 +00:00
|
|
|
vmx->guest_msrs[i].data,
|
|
|
|
vmx->guest_msrs[i].mask);
|
2007-05-02 13:54:03 +00:00
|
|
|
}
|
|
|
|
|
2008-06-24 08:48:49 +00:00
|
|
|
static void __vmx_load_host_state(struct vcpu_vmx *vmx)
|
2007-05-02 13:54:03 +00:00
|
|
|
{
|
2007-07-27 12:13:10 +00:00
|
|
|
if (!vmx->host_state.loaded)
|
2007-05-02 13:54:03 +00:00
|
|
|
return;
|
|
|
|
|
2007-11-18 11:50:24 +00:00
|
|
|
++vmx->vcpu.stat.host_state_reload;
|
2007-07-27 12:13:10 +00:00
|
|
|
vmx->host_state.loaded = 0;
|
2010-11-11 10:37:26 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
if (is_long_mode(&vmx->vcpu))
|
|
|
|
rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
|
|
|
|
#endif
|
2007-08-23 14:33:11 +00:00
|
|
|
if (vmx->host_state.gs_ldt_reload_needed) {
|
2008-07-10 13:53:33 +00:00
|
|
|
kvm_load_ldt(vmx->host_state.ldt_sel);
|
2007-05-02 13:54:03 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2010-10-19 14:46:55 +00:00
|
|
|
load_gs_index(vmx->host_state.gs_sel);
|
|
|
|
#else
|
|
|
|
loadsegment(gs, vmx->host_state.gs_sel);
|
2007-05-02 13:54:03 +00:00
|
|
|
#endif
|
|
|
|
}
|
2010-10-19 16:48:35 +00:00
|
|
|
if (vmx->host_state.fs_reload_needed)
|
|
|
|
loadsegment(fs, vmx->host_state.fs_sel);
|
2012-05-13 16:53:24 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
if (unlikely(vmx->host_state.ds_sel | vmx->host_state.es_sel)) {
|
|
|
|
loadsegment(ds, vmx->host_state.ds_sel);
|
|
|
|
loadsegment(es, vmx->host_state.es_sel);
|
|
|
|
}
|
|
|
|
#endif
|
2007-08-23 14:33:11 +00:00
|
|
|
reload_tss();
|
2009-09-06 12:55:37 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2010-11-11 10:37:26 +00:00
|
|
|
wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
|
2009-09-06 12:55:37 +00:00
|
|
|
#endif
|
2014-02-24 10:55:46 +00:00
|
|
|
if (vmx->host_state.msr_host_bndcfgs)
|
|
|
|
wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
|
2012-09-20 18:01:49 +00:00
|
|
|
/*
|
|
|
|
* If the FPU is not active (through the host task or
|
|
|
|
* the guest vcpu), then restore the cr0.TS bit.
|
|
|
|
*/
|
2015-04-28 10:28:08 +00:00
|
|
|
if (!fpregs_active() && !vmx->vcpu.guest_fpu_loaded)
|
2012-09-20 18:01:49 +00:00
|
|
|
stts();
|
x86: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-17 17:30:40 +00:00
|
|
|
load_gdt(this_cpu_ptr(&host_gdt));
|
2007-05-02 13:54:03 +00:00
|
|
|
}
|
|
|
|
|
2008-06-24 08:48:49 +00:00
|
|
|
static void vmx_load_host_state(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
preempt_disable();
|
|
|
|
__vmx_load_host_state(vmx);
|
|
|
|
preempt_enable();
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
|
|
|
|
* vcpu mutex is already taken.
|
|
|
|
*/
|
2007-07-11 15:17:21 +00:00
|
|
|
static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-07-27 12:13:10 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2010-05-11 10:29:48 +00:00
|
|
|
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2010-05-11 10:29:48 +00:00
|
|
|
if (!vmm_exclusive)
|
|
|
|
kvm_cpu_vmxon(phys_addr);
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
else if (vmx->loaded_vmcs->cpu != cpu)
|
|
|
|
loaded_vmcs_clear(vmx->loaded_vmcs);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
if (per_cpu(current_vmcs, cpu) != vmx->loaded_vmcs->vmcs) {
|
|
|
|
per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs;
|
|
|
|
vmcs_load(vmx->loaded_vmcs->vmcs);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
if (vmx->loaded_vmcs->cpu != cpu) {
|
x86: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-17 17:30:40 +00:00
|
|
|
struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
unsigned long sysenter_esp;
|
|
|
|
|
2010-05-10 09:34:53 +00:00
|
|
|
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
|
2010-05-11 10:29:42 +00:00
|
|
|
local_irq_disable();
|
2012-12-06 15:43:34 +00:00
|
|
|
crash_disable_local_vmclear(cpu);
|
2012-11-28 12:54:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Read loaded_vmcs->cpu should be before fetching
|
|
|
|
* loaded_vmcs->loaded_vmcss_on_cpu_link.
|
|
|
|
* See the comments in __loaded_vmcs_clear().
|
|
|
|
*/
|
|
|
|
smp_rmb();
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link,
|
|
|
|
&per_cpu(loaded_vmcss_on_cpu, cpu));
|
2012-12-06 15:43:34 +00:00
|
|
|
crash_enable_local_vmclear(cpu);
|
2010-05-11 10:29:42 +00:00
|
|
|
local_irq_enable();
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* Linux uses per-cpu TSS and GDT, so set these when switching
|
|
|
|
* processors.
|
|
|
|
*/
|
2008-07-10 13:53:33 +00:00
|
|
|
vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
|
2010-07-26 15:32:39 +00:00
|
|
|
vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
|
|
|
|
vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
vmx->loaded_vmcs->cpu = cpu;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2008-06-24 08:48:49 +00:00
|
|
|
__vmx_load_host_state(to_vmx(vcpu));
|
2010-05-11 10:29:48 +00:00
|
|
|
if (!vmm_exclusive) {
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
__loaded_vmcs_clear(to_vmx(vcpu)->loaded_vmcs);
|
|
|
|
vcpu->cpu = -1;
|
2010-05-11 10:29:48 +00:00
|
|
|
kvm_cpu_vmxoff();
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2007-05-02 17:40:00 +00:00
|
|
|
static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2010-01-24 14:26:40 +00:00
|
|
|
ulong cr0;
|
|
|
|
|
2007-05-02 17:40:00 +00:00
|
|
|
if (vcpu->fpu_active)
|
|
|
|
return;
|
|
|
|
vcpu->fpu_active = 1;
|
2010-01-24 14:26:40 +00:00
|
|
|
cr0 = vmcs_readl(GUEST_CR0);
|
|
|
|
cr0 &= ~(X86_CR0_TS | X86_CR0_MP);
|
|
|
|
cr0 |= kvm_read_cr0_bits(vcpu, X86_CR0_TS | X86_CR0_MP);
|
|
|
|
vmcs_writel(GUEST_CR0, cr0);
|
2007-05-02 17:40:00 +00:00
|
|
|
update_exception_bitmap(vcpu);
|
2009-12-30 16:07:40 +00:00
|
|
|
vcpu->arch.cr0_guest_owned_bits = X86_CR0_TS;
|
KVM: nVMX: Further fixes for lazy FPU loading
KVM's "Lazy FPU loading" means that sometimes L0 needs to set CR0.TS, even
if a guest didn't set it. Moreover, L0 must also trap CR0.TS changes and
NM exceptions, even if we have a guest hypervisor (L1) who didn't want these
traps. And of course, conversely: If L1 wanted to trap these events, we
must let it, even if L0 is not interested in them.
This patch fixes some existing KVM code (in update_exception_bitmap(),
vmx_fpu_activate(), vmx_fpu_deactivate()) to do the correct merging of L0's
and L1's needs. Note that handle_cr() was already fixed in the above patch,
and that new code in introduced in previous patches already handles CR0
correctly (see prepare_vmcs02(), prepare_vmcs12(), and nested_vmx_vmexit()).
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:15:08 +00:00
|
|
|
if (is_guest_mode(vcpu))
|
|
|
|
vcpu->arch.cr0_guest_owned_bits &=
|
|
|
|
~get_vmcs12(vcpu)->cr0_guest_host_mask;
|
2009-12-30 16:07:40 +00:00
|
|
|
vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
|
2007-05-02 17:40:00 +00:00
|
|
|
}
|
|
|
|
|
2009-12-30 16:07:40 +00:00
|
|
|
static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
/*
|
|
|
|
* Return the cr0 value that a nested guest would read. This is a combination
|
|
|
|
* of the real cr0 used to run the guest (guest_cr0), and the bits shadowed by
|
|
|
|
* its hypervisor (cr0_read_shadow).
|
|
|
|
*/
|
|
|
|
static inline unsigned long nested_read_cr0(struct vmcs12 *fields)
|
|
|
|
{
|
|
|
|
return (fields->guest_cr0 & ~fields->cr0_guest_host_mask) |
|
|
|
|
(fields->cr0_read_shadow & fields->cr0_guest_host_mask);
|
|
|
|
}
|
|
|
|
static inline unsigned long nested_read_cr4(struct vmcs12 *fields)
|
|
|
|
{
|
|
|
|
return (fields->guest_cr4 & ~fields->cr4_guest_host_mask) |
|
|
|
|
(fields->cr4_read_shadow & fields->cr4_guest_host_mask);
|
|
|
|
}
|
|
|
|
|
2007-05-02 17:40:00 +00:00
|
|
|
static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
KVM: nVMX: Further fixes for lazy FPU loading
KVM's "Lazy FPU loading" means that sometimes L0 needs to set CR0.TS, even
if a guest didn't set it. Moreover, L0 must also trap CR0.TS changes and
NM exceptions, even if we have a guest hypervisor (L1) who didn't want these
traps. And of course, conversely: If L1 wanted to trap these events, we
must let it, even if L0 is not interested in them.
This patch fixes some existing KVM code (in update_exception_bitmap(),
vmx_fpu_activate(), vmx_fpu_deactivate()) to do the correct merging of L0's
and L1's needs. Note that handle_cr() was already fixed in the above patch,
and that new code in introduced in previous patches already handles CR0
correctly (see prepare_vmcs02(), prepare_vmcs12(), and nested_vmx_vmexit()).
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:15:08 +00:00
|
|
|
/* Note that there is no vcpu->fpu_active = 0 here. The caller must
|
|
|
|
* set this *before* calling this function.
|
|
|
|
*/
|
2009-12-30 16:07:40 +00:00
|
|
|
vmx_decache_cr0_guest_bits(vcpu);
|
2010-01-24 14:26:40 +00:00
|
|
|
vmcs_set_bits(GUEST_CR0, X86_CR0_TS | X86_CR0_MP);
|
2007-05-02 17:40:00 +00:00
|
|
|
update_exception_bitmap(vcpu);
|
2009-12-30 16:07:40 +00:00
|
|
|
vcpu->arch.cr0_guest_owned_bits = 0;
|
|
|
|
vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
|
KVM: nVMX: Further fixes for lazy FPU loading
KVM's "Lazy FPU loading" means that sometimes L0 needs to set CR0.TS, even
if a guest didn't set it. Moreover, L0 must also trap CR0.TS changes and
NM exceptions, even if we have a guest hypervisor (L1) who didn't want these
traps. And of course, conversely: If L1 wanted to trap these events, we
must let it, even if L0 is not interested in them.
This patch fixes some existing KVM code (in update_exception_bitmap(),
vmx_fpu_activate(), vmx_fpu_deactivate()) to do the correct merging of L0's
and L1's needs. Note that handle_cr() was already fixed in the above patch,
and that new code in introduced in previous patches already handles CR0
correctly (see prepare_vmcs02(), prepare_vmcs12(), and nested_vmx_vmexit()).
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:15:08 +00:00
|
|
|
if (is_guest_mode(vcpu)) {
|
|
|
|
/*
|
|
|
|
* L1's specified read shadow might not contain the TS bit,
|
|
|
|
* so now that we turned on shadowing of this bit, we need to
|
|
|
|
* set this bit of the shadow. Like in nested_vmx_run we need
|
|
|
|
* nested_read_cr0(vmcs12), but vmcs12->guest_cr0 is not yet
|
|
|
|
* up-to-date here because we just decached cr0.TS (and we'll
|
|
|
|
* only update vmcs12->guest_cr0 on nested exit).
|
|
|
|
*/
|
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
vmcs12->guest_cr0 = (vmcs12->guest_cr0 & ~X86_CR0_TS) |
|
|
|
|
(vcpu->arch.cr0 & X86_CR0_TS);
|
|
|
|
vmcs_writel(CR0_READ_SHADOW, nested_read_cr0(vmcs12));
|
|
|
|
} else
|
|
|
|
vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
|
2007-05-02 17:40:00 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2010-04-08 15:19:35 +00:00
|
|
|
unsigned long rflags, save_rflags;
|
2009-08-12 12:29:37 +00:00
|
|
|
|
2011-03-07 10:51:22 +00:00
|
|
|
if (!test_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail)) {
|
|
|
|
__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
|
|
|
|
rflags = vmcs_readl(GUEST_RFLAGS);
|
|
|
|
if (to_vmx(vcpu)->rmode.vm86_active) {
|
|
|
|
rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
|
|
|
|
save_rflags = to_vmx(vcpu)->rmode.save_rflags;
|
|
|
|
rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
|
|
|
|
}
|
|
|
|
to_vmx(vcpu)->rflags = rflags;
|
2010-04-08 15:19:35 +00:00
|
|
|
}
|
2011-03-07 10:51:22 +00:00
|
|
|
return to_vmx(vcpu)->rflags;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
|
|
|
|
{
|
2011-03-07 10:51:22 +00:00
|
|
|
__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
|
|
|
|
to_vmx(vcpu)->rflags = rflags;
|
2010-04-08 15:19:35 +00:00
|
|
|
if (to_vmx(vcpu)->rmode.vm86_active) {
|
|
|
|
to_vmx(vcpu)->rmode.save_rflags = rflags;
|
2008-01-30 12:31:27 +00:00
|
|
|
rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
|
2010-04-08 15:19:35 +00:00
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_writel(GUEST_RFLAGS, rflags);
|
|
|
|
}
|
|
|
|
|
2014-05-20 12:29:47 +00:00
|
|
|
static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu)
|
2009-05-12 20:21:05 +00:00
|
|
|
{
|
|
|
|
u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (interruptibility & GUEST_INTR_STATE_STI)
|
2010-02-19 18:38:07 +00:00
|
|
|
ret |= KVM_X86_SHADOW_INT_STI;
|
2009-05-12 20:21:05 +00:00
|
|
|
if (interruptibility & GUEST_INTR_STATE_MOV_SS)
|
2010-02-19 18:38:07 +00:00
|
|
|
ret |= KVM_X86_SHADOW_INT_MOV_SS;
|
2009-05-12 20:21:05 +00:00
|
|
|
|
2014-05-20 12:29:47 +00:00
|
|
|
return ret;
|
2009-05-12 20:21:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
|
|
|
|
{
|
|
|
|
u32 interruptibility_old = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
|
|
|
|
u32 interruptibility = interruptibility_old;
|
|
|
|
|
|
|
|
interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS);
|
|
|
|
|
2010-02-19 18:38:07 +00:00
|
|
|
if (mask & KVM_X86_SHADOW_INT_MOV_SS)
|
2009-05-12 20:21:05 +00:00
|
|
|
interruptibility |= GUEST_INTR_STATE_MOV_SS;
|
2010-02-19 18:38:07 +00:00
|
|
|
else if (mask & KVM_X86_SHADOW_INT_STI)
|
2009-05-12 20:21:05 +00:00
|
|
|
interruptibility |= GUEST_INTR_STATE_STI;
|
|
|
|
|
|
|
|
if ((interruptibility != interruptibility_old))
|
|
|
|
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility);
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long rip;
|
|
|
|
|
2008-06-27 17:58:02 +00:00
|
|
|
rip = kvm_rip_read(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
|
2008-06-27 17:58:02 +00:00
|
|
|
kvm_rip_write(vcpu, rip);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2009-05-12 20:21:05 +00:00
|
|
|
/* skipping an emulated instruction also counts */
|
|
|
|
vmx_set_interrupt_shadow(vcpu, 0);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:13:36 +00:00
|
|
|
/*
|
|
|
|
* KVM wants to inject page-faults which it got to the guest. This function
|
|
|
|
* checks whether in a nested guest, we need to inject them to L1 or L2.
|
|
|
|
*/
|
2013-09-25 09:51:35 +00:00
|
|
|
static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned nr)
|
2011-05-25 20:13:36 +00:00
|
|
|
{
|
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
|
2013-09-25 09:51:35 +00:00
|
|
|
if (!(vmcs12->exception_bitmap & (1u << nr)))
|
2011-05-25 20:13:36 +00:00
|
|
|
return 0;
|
|
|
|
|
2014-01-04 17:47:20 +00:00
|
|
|
nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
|
|
|
|
vmcs_read32(VM_EXIT_INTR_INFO),
|
|
|
|
vmcs_readl(EXIT_QUALIFICATION));
|
2011-05-25 20:13:36 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-11-25 11:41:11 +00:00
|
|
|
static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
|
2010-04-22 10:33:13 +00:00
|
|
|
bool has_error_code, u32 error_code,
|
|
|
|
bool reinject)
|
2007-11-25 11:41:11 +00:00
|
|
|
{
|
2008-07-14 10:28:51 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2008-12-15 12:52:10 +00:00
|
|
|
u32 intr_info = nr | INTR_INFO_VALID_MASK;
|
2008-07-14 10:28:51 +00:00
|
|
|
|
2013-09-25 09:51:35 +00:00
|
|
|
if (!reinject && is_guest_mode(vcpu) &&
|
|
|
|
nested_vmx_check_exception(vcpu, nr))
|
2011-05-25 20:13:36 +00:00
|
|
|
return;
|
|
|
|
|
2008-12-15 12:52:10 +00:00
|
|
|
if (has_error_code) {
|
2008-07-14 10:28:51 +00:00
|
|
|
vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
|
2008-12-15 12:52:10 +00:00
|
|
|
intr_info |= INTR_INFO_DELIVER_CODE_MASK;
|
|
|
|
}
|
2008-07-14 10:28:51 +00:00
|
|
|
|
2009-06-09 11:10:45 +00:00
|
|
|
if (vmx->rmode.vm86_active) {
|
2011-04-13 14:12:54 +00:00
|
|
|
int inc_eip = 0;
|
|
|
|
if (kvm_exception_is_soft(nr))
|
|
|
|
inc_eip = vcpu->arch.event_exit_inst_len;
|
|
|
|
if (kvm_inject_realmode_interrupt(vcpu, nr, inc_eip) != EMULATE_DONE)
|
2010-09-19 12:34:07 +00:00
|
|
|
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
2008-07-14 10:28:51 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-05-11 10:35:50 +00:00
|
|
|
if (kvm_exception_is_soft(nr)) {
|
|
|
|
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
|
|
|
|
vmx->vcpu.arch.event_exit_inst_len);
|
2008-12-15 12:52:10 +00:00
|
|
|
intr_info |= INTR_TYPE_SOFT_EXCEPTION;
|
|
|
|
} else
|
|
|
|
intr_info |= INTR_TYPE_HARD_EXCEPTION;
|
|
|
|
|
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
|
2007-11-25 11:41:11 +00:00
|
|
|
}
|
|
|
|
|
2009-12-18 08:48:47 +00:00
|
|
|
static bool vmx_rdtscp_supported(void)
|
|
|
|
{
|
|
|
|
return cpu_has_vmx_rdtscp();
|
|
|
|
}
|
|
|
|
|
2012-07-02 01:18:48 +00:00
|
|
|
static bool vmx_invpcid_supported(void)
|
|
|
|
{
|
|
|
|
return cpu_has_vmx_invpcid() && enable_ept;
|
|
|
|
}
|
|
|
|
|
2007-05-17 15:55:15 +00:00
|
|
|
/*
|
|
|
|
* Swap MSR entry in host/guest MSR entry array.
|
|
|
|
*/
|
2007-07-30 06:31:43 +00:00
|
|
|
static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
|
2007-05-17 15:55:15 +00:00
|
|
|
{
|
2009-09-07 08:14:12 +00:00
|
|
|
struct shared_msr_entry tmp;
|
2007-07-27 12:13:10 +00:00
|
|
|
|
|
|
|
tmp = vmx->guest_msrs[to];
|
|
|
|
vmx->guest_msrs[to] = vmx->guest_msrs[from];
|
|
|
|
vmx->guest_msrs[from] = tmp;
|
2007-05-17 15:55:15 +00:00
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:50 +00:00
|
|
|
static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long *msr_bitmap;
|
|
|
|
|
2015-03-04 06:31:56 +00:00
|
|
|
if (is_guest_mode(vcpu))
|
|
|
|
msr_bitmap = vmx_msr_bitmap_nested;
|
2015-05-04 06:32:32 +00:00
|
|
|
else if (vcpu->arch.apic_base & X2APIC_ENABLE) {
|
2013-01-25 02:18:50 +00:00
|
|
|
if (is_long_mode(vcpu))
|
|
|
|
msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
|
|
|
|
else
|
|
|
|
msr_bitmap = vmx_msr_bitmap_legacy_x2apic;
|
|
|
|
} else {
|
|
|
|
if (is_long_mode(vcpu))
|
|
|
|
msr_bitmap = vmx_msr_bitmap_longmode;
|
|
|
|
else
|
|
|
|
msr_bitmap = vmx_msr_bitmap_legacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmcs_write64(MSR_BITMAP, __pa(msr_bitmap));
|
|
|
|
}
|
|
|
|
|
2007-04-19 10:22:48 +00:00
|
|
|
/*
|
|
|
|
* Set up the vmcs to automatically save and restore system
|
|
|
|
* msrs. Don't touch the 64-bit msrs if the guest is in legacy
|
|
|
|
* mode, as fiddling with msrs is very expensive.
|
|
|
|
*/
|
2007-07-30 06:31:43 +00:00
|
|
|
static void setup_msrs(struct vcpu_vmx *vmx)
|
2007-04-19 10:22:48 +00:00
|
|
|
{
|
2009-09-07 08:14:12 +00:00
|
|
|
int save_nmsrs, index;
|
2007-04-19 10:22:48 +00:00
|
|
|
|
2007-05-17 15:55:15 +00:00
|
|
|
save_nmsrs = 0;
|
|
|
|
#ifdef CONFIG_X86_64
|
2007-07-30 06:31:43 +00:00
|
|
|
if (is_long_mode(&vmx->vcpu)) {
|
|
|
|
index = __find_msr_index(vmx, MSR_SYSCALL_MASK);
|
2007-05-17 15:55:15 +00:00
|
|
|
if (index >= 0)
|
2007-07-30 06:31:43 +00:00
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
|
|
|
index = __find_msr_index(vmx, MSR_LSTAR);
|
2007-05-17 15:55:15 +00:00
|
|
|
if (index >= 0)
|
2007-07-30 06:31:43 +00:00
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
|
|
|
index = __find_msr_index(vmx, MSR_CSTAR);
|
2007-05-17 15:55:15 +00:00
|
|
|
if (index >= 0)
|
2007-07-30 06:31:43 +00:00
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
2009-12-18 08:48:47 +00:00
|
|
|
index = __find_msr_index(vmx, MSR_TSC_AUX);
|
|
|
|
if (index >= 0 && vmx->rdtscp_enabled)
|
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
2007-05-17 15:55:15 +00:00
|
|
|
/*
|
2010-07-17 13:03:26 +00:00
|
|
|
* MSR_STAR is only needed on long mode guests, and only
|
2007-05-17 15:55:15 +00:00
|
|
|
* if efer.sce is enabled.
|
|
|
|
*/
|
2010-07-17 13:03:26 +00:00
|
|
|
index = __find_msr_index(vmx, MSR_STAR);
|
2010-01-21 13:31:50 +00:00
|
|
|
if ((index >= 0) && (vmx->vcpu.arch.efer & EFER_SCE))
|
2007-07-30 06:31:43 +00:00
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
2007-05-17 15:55:15 +00:00
|
|
|
}
|
|
|
|
#endif
|
2009-10-29 09:00:16 +00:00
|
|
|
index = __find_msr_index(vmx, MSR_EFER);
|
|
|
|
if (index >= 0 && update_transition_efer(vmx, index))
|
2009-09-07 08:14:12 +00:00
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
2007-04-19 10:22:48 +00:00
|
|
|
|
2009-09-07 08:14:12 +00:00
|
|
|
vmx->save_nmsrs = save_nmsrs;
|
2009-02-24 20:26:47 +00:00
|
|
|
|
2013-01-25 02:18:50 +00:00
|
|
|
if (cpu_has_vmx_msr_bitmap())
|
|
|
|
vmx_set_msr_bitmap(&vmx->vcpu);
|
2007-04-19 10:22:48 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2015-06-25 16:44:07 +00:00
|
|
|
host_tsc = rdtsc();
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
tsc_offset = vmcs_read64(TSC_OFFSET);
|
|
|
|
return host_tsc + tsc_offset;
|
|
|
|
}
|
|
|
|
|
2011-08-02 12:54:20 +00:00
|
|
|
/*
|
|
|
|
* Like guest_read_tsc, but always returns L1's notion of the timestamp
|
|
|
|
* counter, even if a nested guest (L2) is currently running.
|
|
|
|
*/
|
2014-08-26 11:27:46 +00:00
|
|
|
static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
|
2011-08-02 12:54:20 +00:00
|
|
|
{
|
2012-11-28 01:28:58 +00:00
|
|
|
u64 tsc_offset;
|
2011-08-02 12:54:20 +00:00
|
|
|
|
|
|
|
tsc_offset = is_guest_mode(vcpu) ?
|
|
|
|
to_vmx(vcpu)->nested.vmcs01_tsc_offset :
|
|
|
|
vmcs_read64(TSC_OFFSET);
|
|
|
|
return host_tsc + tsc_offset;
|
|
|
|
}
|
|
|
|
|
2011-03-25 08:44:49 +00:00
|
|
|
/*
|
KVM: Infrastructure for software and hardware based TSC rate scaling
This requires some restructuring; rather than use 'virtual_tsc_khz'
to indicate whether hardware rate scaling is in effect, we consider
each VCPU to always have a virtual TSC rate. Instead, there is new
logic above the vendor-specific hardware scaling that decides whether
it is even necessary to use and updates all rate variables used by
common code. This means we can simply query the virtual rate at
any point, which is needed for software rate scaling.
There is also now a threshold added to the TSC rate scaling; minor
differences and variations of measured TSC rate can accidentally
provoke rate scaling to be used when it is not needed. Instead,
we have a tolerance variable called tsc_tolerance_ppm, which is
the maximum variation from user requested rate at which scaling
will be used. The default is 250ppm, which is the half the
threshold for NTP adjustment, allowing for some hardware variation.
In the event that hardware rate scaling is not available, we can
kludge a bit by forcing TSC catchup to turn on when a faster than
hardware speed has been requested, but there is nothing available
yet for the reverse case; this requires a trap and emulate software
implementation for RDTSC, which is still forthcoming.
[avi: fix 64-bit division on i386]
Signed-off-by: Zachary Amsden <zamsden@gmail.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2012-02-03 17:43:50 +00:00
|
|
|
* Engage any workarounds for mis-matched TSC rates. Currently limited to
|
|
|
|
* software catchup for faster rates on slower CPUs.
|
2011-03-25 08:44:49 +00:00
|
|
|
*/
|
KVM: Infrastructure for software and hardware based TSC rate scaling
This requires some restructuring; rather than use 'virtual_tsc_khz'
to indicate whether hardware rate scaling is in effect, we consider
each VCPU to always have a virtual TSC rate. Instead, there is new
logic above the vendor-specific hardware scaling that decides whether
it is even necessary to use and updates all rate variables used by
common code. This means we can simply query the virtual rate at
any point, which is needed for software rate scaling.
There is also now a threshold added to the TSC rate scaling; minor
differences and variations of measured TSC rate can accidentally
provoke rate scaling to be used when it is not needed. Instead,
we have a tolerance variable called tsc_tolerance_ppm, which is
the maximum variation from user requested rate at which scaling
will be used. The default is 250ppm, which is the half the
threshold for NTP adjustment, allowing for some hardware variation.
In the event that hardware rate scaling is not available, we can
kludge a bit by forcing TSC catchup to turn on when a faster than
hardware speed has been requested, but there is nothing available
yet for the reverse case; this requires a trap and emulate software
implementation for RDTSC, which is still forthcoming.
[avi: fix 64-bit division on i386]
Signed-off-by: Zachary Amsden <zamsden@gmail.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2012-02-03 17:43:50 +00:00
|
|
|
static void vmx_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
|
2011-03-25 08:44:49 +00:00
|
|
|
{
|
KVM: Infrastructure for software and hardware based TSC rate scaling
This requires some restructuring; rather than use 'virtual_tsc_khz'
to indicate whether hardware rate scaling is in effect, we consider
each VCPU to always have a virtual TSC rate. Instead, there is new
logic above the vendor-specific hardware scaling that decides whether
it is even necessary to use and updates all rate variables used by
common code. This means we can simply query the virtual rate at
any point, which is needed for software rate scaling.
There is also now a threshold added to the TSC rate scaling; minor
differences and variations of measured TSC rate can accidentally
provoke rate scaling to be used when it is not needed. Instead,
we have a tolerance variable called tsc_tolerance_ppm, which is
the maximum variation from user requested rate at which scaling
will be used. The default is 250ppm, which is the half the
threshold for NTP adjustment, allowing for some hardware variation.
In the event that hardware rate scaling is not available, we can
kludge a bit by forcing TSC catchup to turn on when a faster than
hardware speed has been requested, but there is nothing available
yet for the reverse case; this requires a trap and emulate software
implementation for RDTSC, which is still forthcoming.
[avi: fix 64-bit division on i386]
Signed-off-by: Zachary Amsden <zamsden@gmail.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2012-02-03 17:43:50 +00:00
|
|
|
if (!scale)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (user_tsc_khz > tsc_khz) {
|
|
|
|
vcpu->arch.tsc_catchup = 1;
|
|
|
|
vcpu->arch.tsc_always_catchup = 1;
|
|
|
|
} else
|
|
|
|
WARN(1, "user requested TSC rate below hardware speed\n");
|
2011-03-25 08:44:49 +00:00
|
|
|
}
|
|
|
|
|
2012-11-29 20:42:50 +00:00
|
|
|
static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return vmcs_read64(TSC_OFFSET);
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
2010-08-20 08:07:17 +00:00
|
|
|
* writes 'offset' into guest's timestamp counter offset register
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
*/
|
2010-08-20 08:07:17 +00:00
|
|
|
static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2011-08-02 12:54:52 +00:00
|
|
|
if (is_guest_mode(vcpu)) {
|
2011-05-25 20:15:39 +00:00
|
|
|
/*
|
2011-08-02 12:54:52 +00:00
|
|
|
* We're here if L1 chose not to trap WRMSR to TSC. According
|
|
|
|
* to the spec, this should set L1's TSC; The offset that L1
|
|
|
|
* set for L2 remains unchanged, and still needs to be added
|
|
|
|
* to the newly set TSC to get L2's TSC.
|
2011-05-25 20:15:39 +00:00
|
|
|
*/
|
2011-08-02 12:54:52 +00:00
|
|
|
struct vmcs12 *vmcs12;
|
|
|
|
to_vmx(vcpu)->nested.vmcs01_tsc_offset = offset;
|
|
|
|
/* recalculate vmcs02.TSC_OFFSET: */
|
|
|
|
vmcs12 = get_vmcs12(vcpu);
|
|
|
|
vmcs_write64(TSC_OFFSET, offset +
|
|
|
|
(nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETING) ?
|
|
|
|
vmcs12->tsc_offset : 0));
|
|
|
|
} else {
|
2013-06-12 07:43:44 +00:00
|
|
|
trace_kvm_write_tsc_offset(vcpu->vcpu_id,
|
|
|
|
vmcs_read64(TSC_OFFSET), offset);
|
2011-08-02 12:54:52 +00:00
|
|
|
vmcs_write64(TSC_OFFSET, offset);
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2012-02-03 17:43:55 +00:00
|
|
|
static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool host)
|
2010-08-20 08:07:23 +00:00
|
|
|
{
|
|
|
|
u64 offset = vmcs_read64(TSC_OFFSET);
|
2013-06-12 07:43:44 +00:00
|
|
|
|
2010-08-20 08:07:23 +00:00
|
|
|
vmcs_write64(TSC_OFFSET, offset + adjustment);
|
2011-05-25 20:15:39 +00:00
|
|
|
if (is_guest_mode(vcpu)) {
|
|
|
|
/* Even when running L2, the adjustment needs to apply to L1 */
|
|
|
|
to_vmx(vcpu)->nested.vmcs01_tsc_offset += adjustment;
|
2013-06-12 07:43:44 +00:00
|
|
|
} else
|
|
|
|
trace_kvm_write_tsc_offset(vcpu->vcpu_id, offset,
|
|
|
|
offset + adjustment);
|
2010-08-20 08:07:23 +00:00
|
|
|
}
|
|
|
|
|
2011-03-25 08:44:50 +00:00
|
|
|
static u64 vmx_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
|
|
|
|
{
|
2015-06-25 16:44:07 +00:00
|
|
|
return target_tsc - rdtsc();
|
2011-03-25 08:44:50 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:02:23 +00:00
|
|
|
static bool guest_cpuid_has_vmx(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, 1, 0);
|
|
|
|
return best && (best->ecx & (1 << (X86_FEATURE_VMX & 31)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* nested_vmx_allowed() checks whether a guest should be allowed to use VMX
|
|
|
|
* instructions and MSRs (i.e., nested VMX). Nested VMX is disabled for
|
|
|
|
* all guests if the "nested" module option is off, and can also be disabled
|
|
|
|
* for a single guest by disabling its VMX cpuid bit.
|
|
|
|
*/
|
|
|
|
static inline bool nested_vmx_allowed(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return nested && guest_cpuid_has_vmx(vcpu);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:04:25 +00:00
|
|
|
/*
|
|
|
|
* nested_vmx_setup_ctls_msrs() sets up variables containing the values to be
|
|
|
|
* returned for the various VMX controls MSRs when nested VMX is enabled.
|
|
|
|
* The same values should also be used to verify that vmcs12 control fields are
|
|
|
|
* valid during nested entry from L1 to L2.
|
|
|
|
* Each of these control msrs has a low and high 32-bit half: A low bit is on
|
|
|
|
* if the corresponding bit in the (32-bit) control field *must* be on, and a
|
|
|
|
* bit in the high half is on if the corresponding bit in the control field
|
|
|
|
* may be on. See also vmx_control_verify().
|
|
|
|
*/
|
2015-02-03 15:56:30 +00:00
|
|
|
static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
|
2011-05-25 20:04:25 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Note that as a general rule, the high half of the MSRs (bits in
|
|
|
|
* the control fields which may be 1) should be initialized by the
|
|
|
|
* intersection of the underlying hardware's MSR (i.e., features which
|
|
|
|
* can be supported) and the list of features we want to expose -
|
|
|
|
* because they are known to be properly supported in our code.
|
|
|
|
* Also, usually, the low half of the MSRs (bits which must be 1) can
|
|
|
|
* be set to 0, meaning that L1 may turn off any of these bits. The
|
|
|
|
* reason is that if one of these bits is necessary, it will appear
|
|
|
|
* in vmcs01 and prepare_vmcs02, when it bitwise-or's the control
|
|
|
|
* fields of vmcs01 and vmcs02, will turn these bits off - and
|
|
|
|
* nested_vmx_exit_handled() will not pass related exits to L1.
|
|
|
|
* These rules have exceptions below.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* pin-based controls */
|
2013-03-13 10:30:50 +00:00
|
|
|
rdmsr(MSR_IA32_VMX_PINBASED_CTLS,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_high);
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_low |=
|
|
|
|
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR;
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_high &=
|
|
|
|
PIN_BASED_EXT_INTR_MASK |
|
|
|
|
PIN_BASED_NMI_EXITING |
|
|
|
|
PIN_BASED_VIRTUAL_NMIS;
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_high |=
|
|
|
|
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
|
2013-03-13 10:31:24 +00:00
|
|
|
PIN_BASED_VMX_PREEMPTION_TIMER;
|
2015-07-29 10:05:37 +00:00
|
|
|
if (vmx_cpu_uses_apicv(&vmx->vcpu))
|
2015-02-03 15:58:17 +00:00
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_high |=
|
|
|
|
PIN_BASED_POSTED_INTR;
|
2011-05-25 20:04:25 +00:00
|
|
|
|
2014-06-16 11:59:40 +00:00
|
|
|
/* exit controls */
|
2013-08-06 10:41:45 +00:00
|
|
|
rdmsr(MSR_IA32_VMX_EXIT_CTLS,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_exit_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_high);
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_low =
|
|
|
|
VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR;
|
2014-04-19 22:17:46 +00:00
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_exit_ctls_high &=
|
2011-05-25 20:04:25 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2013-08-06 10:41:45 +00:00
|
|
|
VM_EXIT_HOST_ADDR_SPACE_SIZE |
|
2011-05-25 20:04:25 +00:00
|
|
|
#endif
|
2014-03-07 19:03:13 +00:00
|
|
|
VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT;
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_exit_ctls_high |=
|
|
|
|
VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |
|
2014-03-07 19:03:13 +00:00
|
|
|
VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
|
2014-04-19 22:17:46 +00:00
|
|
|
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT;
|
|
|
|
|
2014-02-24 11:30:04 +00:00
|
|
|
if (vmx_mpx_supported())
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
|
2011-05-25 20:04:25 +00:00
|
|
|
|
2014-06-16 11:59:43 +00:00
|
|
|
/* We support free control of debug control saving. */
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_true_exit_ctls_low =
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_low &
|
2014-06-16 11:59:43 +00:00
|
|
|
~VM_EXIT_SAVE_DEBUG_CONTROLS;
|
|
|
|
|
2011-05-25 20:04:25 +00:00
|
|
|
/* entry controls */
|
|
|
|
rdmsr(MSR_IA32_VMX_ENTRY_CTLS,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_entry_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_high);
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_low =
|
|
|
|
VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR;
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_high &=
|
2013-08-06 08:39:56 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
VM_ENTRY_IA32E_MODE |
|
|
|
|
#endif
|
|
|
|
VM_ENTRY_LOAD_IA32_PAT;
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_entry_ctls_high |=
|
|
|
|
(VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
|
2014-02-24 11:30:04 +00:00
|
|
|
if (vmx_mpx_supported())
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
|
2013-08-06 08:39:56 +00:00
|
|
|
|
2014-06-16 11:59:43 +00:00
|
|
|
/* We support free control of debug control loading. */
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_true_entry_ctls_low =
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_low &
|
2014-06-16 11:59:43 +00:00
|
|
|
~VM_ENTRY_LOAD_DEBUG_CONTROLS;
|
|
|
|
|
2011-05-25 20:04:25 +00:00
|
|
|
/* cpu-based controls */
|
|
|
|
rdmsr(MSR_IA32_VMX_PROCBASED_CTLS,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_procbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_high);
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_low =
|
|
|
|
CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR;
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_high &=
|
2013-10-23 16:43:09 +00:00
|
|
|
CPU_BASED_VIRTUAL_INTR_PENDING |
|
|
|
|
CPU_BASED_VIRTUAL_NMI_PENDING | CPU_BASED_USE_TSC_OFFSETING |
|
2011-05-25 20:04:25 +00:00
|
|
|
CPU_BASED_HLT_EXITING | CPU_BASED_INVLPG_EXITING |
|
|
|
|
CPU_BASED_MWAIT_EXITING | CPU_BASED_CR3_LOAD_EXITING |
|
|
|
|
CPU_BASED_CR3_STORE_EXITING |
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING |
|
|
|
|
#endif
|
|
|
|
CPU_BASED_MOV_DR_EXITING | CPU_BASED_UNCOND_IO_EXITING |
|
2015-07-05 17:08:57 +00:00
|
|
|
CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MONITOR_TRAP_FLAG |
|
|
|
|
CPU_BASED_MONITOR_EXITING | CPU_BASED_RDPMC_EXITING |
|
|
|
|
CPU_BASED_RDTSC_EXITING | CPU_BASED_PAUSE_EXITING |
|
|
|
|
CPU_BASED_TPR_SHADOW | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
|
2011-05-25 20:04:25 +00:00
|
|
|
/*
|
|
|
|
* We can allow some features even when not supported by the
|
|
|
|
* hardware. For example, L1 can specify an MSR bitmap - and we
|
|
|
|
* can use it to avoid exits to L1 - even when L0 runs L2
|
|
|
|
* without MSR bitmaps.
|
|
|
|
*/
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_procbased_ctls_high |=
|
|
|
|
CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
|
2014-06-16 11:59:42 +00:00
|
|
|
CPU_BASED_USE_MSR_BITMAPS;
|
2011-05-25 20:04:25 +00:00
|
|
|
|
2014-06-16 11:59:41 +00:00
|
|
|
/* We support free control of CR3 access interception. */
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_true_procbased_ctls_low =
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_low &
|
2014-06-16 11:59:41 +00:00
|
|
|
~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING);
|
|
|
|
|
2011-05-25 20:04:25 +00:00
|
|
|
/* secondary cpu-based controls */
|
|
|
|
rdmsr(MSR_IA32_VMX_PROCBASED_CTLS2,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_secondary_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high);
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_low = 0;
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high &=
|
2013-02-23 21:34:39 +00:00
|
|
|
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
|
2015-03-23 18:27:19 +00:00
|
|
|
SECONDARY_EXEC_RDTSCP |
|
2015-02-03 15:56:03 +00:00
|
|
|
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
|
2015-02-03 15:57:18 +00:00
|
|
|
SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
2015-02-03 15:57:51 +00:00
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
|
2014-12-04 11:11:07 +00:00
|
|
|
SECONDARY_EXEC_WBINVD_EXITING |
|
|
|
|
SECONDARY_EXEC_XSAVES;
|
2013-03-13 15:06:41 +00:00
|
|
|
|
2013-08-07 12:59:22 +00:00
|
|
|
if (enable_ept) {
|
|
|
|
/* nested EPT: emulate EPT also to L1 */
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high |=
|
2015-03-17 13:02:32 +00:00
|
|
|
SECONDARY_EXEC_ENABLE_EPT;
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT |
|
2013-10-23 13:40:31 +00:00
|
|
|
VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT |
|
|
|
|
VMX_EPT_INVEPT_BIT;
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_ept_caps &= vmx_capability.ept;
|
2013-08-07 12:59:22 +00:00
|
|
|
/*
|
2014-04-19 22:17:44 +00:00
|
|
|
* For nested guests, we don't do anything specific
|
|
|
|
* for single context invalidation. Hence, only advertise
|
|
|
|
* support for global context invalidation.
|
2013-08-07 12:59:22 +00:00
|
|
|
*/
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT;
|
2013-08-07 12:59:22 +00:00
|
|
|
} else
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_ept_caps = 0;
|
2013-08-07 12:59:22 +00:00
|
|
|
|
2015-03-17 13:02:32 +00:00
|
|
|
if (enable_unrestricted_guest)
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high |=
|
|
|
|
SECONDARY_EXEC_UNRESTRICTED_GUEST;
|
|
|
|
|
2013-03-13 15:06:41 +00:00
|
|
|
/* miscellaneous data */
|
2015-02-03 15:56:30 +00:00
|
|
|
rdmsr(MSR_IA32_VMX_MISC,
|
|
|
|
vmx->nested.nested_vmx_misc_low,
|
|
|
|
vmx->nested.nested_vmx_misc_high);
|
|
|
|
vmx->nested.nested_vmx_misc_low &= VMX_MISC_SAVE_EFER_LMA;
|
|
|
|
vmx->nested.nested_vmx_misc_low |=
|
|
|
|
VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE |
|
2014-03-07 19:03:13 +00:00
|
|
|
VMX_MISC_ACTIVITY_HLT;
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_misc_high = 0;
|
2011-05-25 20:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool vmx_control_verify(u32 control, u32 low, u32 high)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Bits 0 in high must be 0, and bits 1 in low must be 1.
|
|
|
|
*/
|
|
|
|
return ((control & high) | low) == control;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u64 vmx_control_msr(u32 low, u32 high)
|
|
|
|
{
|
|
|
|
return low | ((u64)high << 32);
|
|
|
|
}
|
|
|
|
|
2014-01-04 17:47:22 +00:00
|
|
|
/* Returns 0 on success, non-0 otherwise. */
|
2011-05-25 20:04:25 +00:00
|
|
|
static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
|
|
|
|
{
|
2015-02-03 15:56:30 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
2011-05-25 20:04:25 +00:00
|
|
|
switch (msr_index) {
|
|
|
|
case MSR_IA32_VMX_BASIC:
|
|
|
|
/*
|
|
|
|
* This MSR reports some information about VMX support. We
|
|
|
|
* should return information about the VMX we emulate for the
|
|
|
|
* guest, and the VMCS structure we give it - not about the
|
|
|
|
* VMX support of the underlying hardware.
|
|
|
|
*/
|
2014-06-16 11:59:40 +00:00
|
|
|
*pdata = VMCS12_REVISION | VMX_BASIC_TRUE_CTLS |
|
2011-05-25 20:04:25 +00:00
|
|
|
((u64)VMCS12_SIZE << VMX_BASIC_VMCS_SIZE_SHIFT) |
|
|
|
|
(VMX_BASIC_MEM_TYPE_WB << VMX_BASIC_MEM_TYPE_SHIFT);
|
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
|
|
|
|
case MSR_IA32_VMX_PINBASED_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_high);
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_TRUE_PROCBASED_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_true_procbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_high);
|
2014-06-16 11:59:41 +00:00
|
|
|
break;
|
2011-05-25 20:04:25 +00:00
|
|
|
case MSR_IA32_VMX_PROCBASED_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_high);
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_TRUE_EXIT_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_true_exit_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_high);
|
2014-06-16 11:59:43 +00:00
|
|
|
break;
|
2011-05-25 20:04:25 +00:00
|
|
|
case MSR_IA32_VMX_EXIT_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_high);
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_true_entry_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_high);
|
2014-06-16 11:59:43 +00:00
|
|
|
break;
|
2011-05-25 20:04:25 +00:00
|
|
|
case MSR_IA32_VMX_ENTRY_CTLS:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_high);
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_MISC:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_misc_low,
|
|
|
|
vmx->nested.nested_vmx_misc_high);
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
/*
|
|
|
|
* These MSRs specify bits which the guest must keep fixed (on or off)
|
|
|
|
* while L1 is in VMXON mode (in L1's root mode, or running an L2).
|
|
|
|
* We picked the standard core2 setting.
|
|
|
|
*/
|
|
|
|
#define VMXON_CR0_ALWAYSON (X86_CR0_PE | X86_CR0_PG | X86_CR0_NE)
|
|
|
|
#define VMXON_CR4_ALWAYSON X86_CR4_VMXE
|
|
|
|
case MSR_IA32_VMX_CR0_FIXED0:
|
|
|
|
*pdata = VMXON_CR0_ALWAYSON;
|
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_CR0_FIXED1:
|
|
|
|
*pdata = -1ULL;
|
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_CR4_FIXED0:
|
|
|
|
*pdata = VMXON_CR4_ALWAYSON;
|
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_CR4_FIXED1:
|
|
|
|
*pdata = -1ULL;
|
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_VMCS_ENUM:
|
2014-06-16 11:59:44 +00:00
|
|
|
*pdata = 0x2e; /* highest index: VMX_PREEMPTION_TIMER_VALUE */
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_PROCBASED_CTLS2:
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx_control_msr(
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high);
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_EPT_VPID_CAP:
|
2013-08-07 12:59:22 +00:00
|
|
|
/* Currently, no nested vpid support */
|
2015-02-03 15:56:30 +00:00
|
|
|
*pdata = vmx->nested.nested_vmx_ept_caps;
|
2011-05-25 20:04:25 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 1;
|
2013-07-08 11:12:35 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:04:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* Reads an msr value (of 'msr_index') into 'pdata'.
|
|
|
|
* Returns 0 on success, non-0 otherwise.
|
|
|
|
* Assumes vcpu_load() was already called.
|
|
|
|
*/
|
2015-04-08 13:30:38 +00:00
|
|
|
static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2009-09-07 08:14:12 +00:00
|
|
|
struct shared_msr_entry *msr;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2015-04-08 13:30:38 +00:00
|
|
|
switch (msr_info->index) {
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
case MSR_FS_BASE:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vmcs_readl(GUEST_FS_BASE);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
|
|
|
case MSR_GS_BASE:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vmcs_readl(GUEST_GS_BASE);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
2009-09-06 12:55:37 +00:00
|
|
|
case MSR_KERNEL_GS_BASE:
|
|
|
|
vmx_load_host_state(to_vmx(vcpu));
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = to_vmx(vcpu)->msr_guest_kernel_gs_base;
|
2009-09-06 12:55:37 +00:00
|
|
|
break;
|
2009-09-07 08:14:12 +00:00
|
|
|
#endif
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
case MSR_EFER:
|
2015-04-08 13:30:38 +00:00
|
|
|
return kvm_get_msr_common(vcpu, msr_info);
|
2009-05-15 13:12:05 +00:00
|
|
|
case MSR_IA32_TSC:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = guest_read_tsc();
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_SYSENTER_CS:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_SYSENTER_EIP:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vmcs_readl(GUEST_SYSENTER_EIP);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_SYSENTER_ESP:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vmcs_readl(GUEST_SYSENTER_ESP);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
2014-02-24 10:56:53 +00:00
|
|
|
case MSR_IA32_BNDCFGS:
|
2014-03-05 22:19:52 +00:00
|
|
|
if (!vmx_mpx_supported())
|
|
|
|
return 1;
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vmcs_read64(GUEST_BNDCFGS);
|
2014-02-24 10:56:53 +00:00
|
|
|
break;
|
2014-01-04 17:47:22 +00:00
|
|
|
case MSR_IA32_FEATURE_CONTROL:
|
|
|
|
if (!nested_vmx_allowed(vcpu))
|
|
|
|
return 1;
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = to_vmx(vcpu)->nested.msr_ia32_feature_control;
|
2014-01-04 17:47:22 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
|
|
|
|
if (!nested_vmx_allowed(vcpu))
|
|
|
|
return 1;
|
2015-04-08 13:30:38 +00:00
|
|
|
return vmx_get_vmx_msr(vcpu, msr_info->index, &msr_info->data);
|
2014-12-02 11:14:59 +00:00
|
|
|
case MSR_IA32_XSS:
|
|
|
|
if (!vmx_xsaves_supported())
|
|
|
|
return 1;
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = vcpu->arch.ia32_xss;
|
2014-12-02 11:14:59 +00:00
|
|
|
break;
|
2009-12-18 08:48:47 +00:00
|
|
|
case MSR_TSC_AUX:
|
|
|
|
if (!to_vmx(vcpu)->rdtscp_enabled)
|
|
|
|
return 1;
|
|
|
|
/* Otherwise falls through */
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
default:
|
2015-04-08 13:30:38 +00:00
|
|
|
msr = find_msr_entry(to_vmx(vcpu), msr_info->index);
|
2006-12-30 00:49:48 +00:00
|
|
|
if (msr) {
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info->data = msr->data;
|
2006-12-30 00:49:48 +00:00
|
|
|
break;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
2015-04-08 13:30:38 +00:00
|
|
|
return kvm_get_msr_common(vcpu, msr_info);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-01-04 17:47:22 +00:00
|
|
|
static void vmx_leave_nested(struct kvm_vcpu *vcpu);
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* Writes msr value into into the appropriate "register".
|
|
|
|
* Returns 0 on success, non-0 otherwise.
|
|
|
|
* Assumes vcpu_load() was already called.
|
|
|
|
*/
|
2012-11-29 20:42:12 +00:00
|
|
|
static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-07-27 12:13:10 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-09-07 08:14:12 +00:00
|
|
|
struct shared_msr_entry *msr;
|
2007-05-21 04:28:09 +00:00
|
|
|
int ret = 0;
|
2012-11-29 20:42:12 +00:00
|
|
|
u32 msr_index = msr_info->index;
|
|
|
|
u64 data = msr_info->data;
|
2007-05-21 04:28:09 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
switch (msr_index) {
|
2006-12-30 00:49:48 +00:00
|
|
|
case MSR_EFER:
|
2012-11-29 20:42:12 +00:00
|
|
|
ret = kvm_set_msr_common(vcpu, msr_info);
|
2007-05-21 04:28:09 +00:00
|
|
|
break;
|
2009-03-23 20:13:44 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
case MSR_FS_BASE:
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_writel(GUEST_FS_BASE, data);
|
|
|
|
break;
|
|
|
|
case MSR_GS_BASE:
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_writel(GUEST_GS_BASE, data);
|
|
|
|
break;
|
2009-09-06 12:55:37 +00:00
|
|
|
case MSR_KERNEL_GS_BASE:
|
|
|
|
vmx_load_host_state(vmx);
|
|
|
|
vmx->msr_guest_kernel_gs_base = data;
|
|
|
|
break;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#endif
|
|
|
|
case MSR_IA32_SYSENTER_CS:
|
|
|
|
vmcs_write32(GUEST_SYSENTER_CS, data);
|
|
|
|
break;
|
|
|
|
case MSR_IA32_SYSENTER_EIP:
|
2007-03-06 10:05:53 +00:00
|
|
|
vmcs_writel(GUEST_SYSENTER_EIP, data);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
|
|
|
case MSR_IA32_SYSENTER_ESP:
|
2007-03-06 10:05:53 +00:00
|
|
|
vmcs_writel(GUEST_SYSENTER_ESP, data);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
2014-02-24 10:56:53 +00:00
|
|
|
case MSR_IA32_BNDCFGS:
|
2014-03-05 22:19:52 +00:00
|
|
|
if (!vmx_mpx_supported())
|
|
|
|
return 1;
|
2014-02-24 10:56:53 +00:00
|
|
|
vmcs_write64(GUEST_BNDCFGS, data);
|
|
|
|
break;
|
2009-05-15 13:12:05 +00:00
|
|
|
case MSR_IA32_TSC:
|
2012-11-29 20:42:12 +00:00
|
|
|
kvm_write_tsc(vcpu, msr_info);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
2008-10-09 08:01:55 +00:00
|
|
|
case MSR_IA32_CR_PAT:
|
|
|
|
if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
|
2014-09-18 19:39:44 +00:00
|
|
|
if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
|
|
|
|
return 1;
|
2008-10-09 08:01:55 +00:00
|
|
|
vmcs_write64(GUEST_IA32_PAT, data);
|
|
|
|
vcpu->arch.pat = data;
|
|
|
|
break;
|
|
|
|
}
|
2012-11-29 20:42:12 +00:00
|
|
|
ret = kvm_set_msr_common(vcpu, msr_info);
|
2009-12-18 08:48:47 +00:00
|
|
|
break;
|
2012-11-29 20:42:50 +00:00
|
|
|
case MSR_IA32_TSC_ADJUST:
|
|
|
|
ret = kvm_set_msr_common(vcpu, msr_info);
|
2009-12-18 08:48:47 +00:00
|
|
|
break;
|
2014-01-04 17:47:22 +00:00
|
|
|
case MSR_IA32_FEATURE_CONTROL:
|
|
|
|
if (!nested_vmx_allowed(vcpu) ||
|
|
|
|
(to_vmx(vcpu)->nested.msr_ia32_feature_control &
|
|
|
|
FEATURE_CONTROL_LOCKED && !msr_info->host_initiated))
|
|
|
|
return 1;
|
|
|
|
vmx->nested.msr_ia32_feature_control = data;
|
|
|
|
if (msr_info->host_initiated && data == 0)
|
|
|
|
vmx_leave_nested(vcpu);
|
|
|
|
break;
|
|
|
|
case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
|
|
|
|
return 1; /* they are read-only */
|
2014-12-02 11:14:59 +00:00
|
|
|
case MSR_IA32_XSS:
|
|
|
|
if (!vmx_xsaves_supported())
|
|
|
|
return 1;
|
|
|
|
/*
|
|
|
|
* The only supported bit as of Skylake is bit 8, but
|
|
|
|
* it is not supported on KVM.
|
|
|
|
*/
|
|
|
|
if (data != 0)
|
|
|
|
return 1;
|
|
|
|
vcpu->arch.ia32_xss = data;
|
|
|
|
if (vcpu->arch.ia32_xss != host_xss)
|
|
|
|
add_atomic_switch_msr(vmx, MSR_IA32_XSS,
|
|
|
|
vcpu->arch.ia32_xss, host_xss);
|
|
|
|
else
|
|
|
|
clear_atomic_switch_msr(vmx, MSR_IA32_XSS);
|
|
|
|
break;
|
2009-12-18 08:48:47 +00:00
|
|
|
case MSR_TSC_AUX:
|
|
|
|
if (!vmx->rdtscp_enabled)
|
|
|
|
return 1;
|
|
|
|
/* Check reserved bit, higher 32 bits should be zero */
|
|
|
|
if ((data >> 32) != 0)
|
|
|
|
return 1;
|
|
|
|
/* Otherwise falls through */
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
default:
|
2007-07-30 06:31:43 +00:00
|
|
|
msr = find_msr_entry(vmx, msr_index);
|
2006-12-30 00:49:48 +00:00
|
|
|
if (msr) {
|
2014-08-27 18:16:44 +00:00
|
|
|
u64 old_msr_data = msr->data;
|
2006-12-30 00:49:48 +00:00
|
|
|
msr->data = data;
|
2012-04-18 12:03:04 +00:00
|
|
|
if (msr - vmx->guest_msrs < vmx->save_nmsrs) {
|
|
|
|
preempt_disable();
|
2014-08-27 18:16:44 +00:00
|
|
|
ret = kvm_set_shared_msr(msr->index, msr->data,
|
|
|
|
msr->mask);
|
2012-04-18 12:03:04 +00:00
|
|
|
preempt_enable();
|
2014-08-27 18:16:44 +00:00
|
|
|
if (ret)
|
|
|
|
msr->data = old_msr_data;
|
2012-04-18 12:03:04 +00:00
|
|
|
}
|
2006-12-30 00:49:48 +00:00
|
|
|
break;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
2012-11-29 20:42:12 +00:00
|
|
|
ret = kvm_set_msr_common(vcpu, msr_info);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2007-05-21 04:28:09 +00:00
|
|
|
return ret;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2008-06-27 17:58:02 +00:00
|
|
|
static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2008-06-27 17:58:02 +00:00
|
|
|
__set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
|
|
|
|
switch (reg) {
|
|
|
|
case VCPU_REGS_RSP:
|
|
|
|
vcpu->arch.regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP);
|
|
|
|
break;
|
|
|
|
case VCPU_REGS_RIP:
|
|
|
|
vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP);
|
|
|
|
break;
|
2009-05-31 19:58:47 +00:00
|
|
|
case VCPU_EXREG_PDPTR:
|
|
|
|
if (enable_ept)
|
|
|
|
ept_save_pdptrs(vcpu);
|
|
|
|
break;
|
2008-06-27 17:58:02 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static __init int cpu_has_kvm_support(void)
|
|
|
|
{
|
2008-11-17 21:03:16 +00:00
|
|
|
return cpu_has_vmx();
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static __init int vmx_disabled_by_bios(void)
|
|
|
|
{
|
|
|
|
u64 msr;
|
|
|
|
|
|
|
|
rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
|
2010-04-29 16:09:01 +00:00
|
|
|
if (msr & FEATURE_CONTROL_LOCKED) {
|
2011-02-08 19:45:56 +00:00
|
|
|
/* launched w/ TXT and VMX disabled */
|
2010-04-29 16:09:01 +00:00
|
|
|
if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX)
|
|
|
|
&& tboot_enabled())
|
|
|
|
return 1;
|
2011-02-08 19:45:56 +00:00
|
|
|
/* launched w/o TXT and VMX only enabled w/ TXT */
|
2010-04-29 16:09:01 +00:00
|
|
|
if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX)
|
2011-02-08 19:45:56 +00:00
|
|
|
&& (msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX)
|
2010-11-17 03:40:17 +00:00
|
|
|
&& !tboot_enabled()) {
|
|
|
|
printk(KERN_WARNING "kvm: disable TXT in the BIOS or "
|
2011-02-08 19:45:56 +00:00
|
|
|
"activate TXT before enabling KVM\n");
|
2010-04-29 16:09:01 +00:00
|
|
|
return 1;
|
2010-11-17 03:40:17 +00:00
|
|
|
}
|
2011-02-08 19:45:56 +00:00
|
|
|
/* launched w/o TXT and VMX disabled */
|
|
|
|
if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX)
|
|
|
|
&& !tboot_enabled())
|
|
|
|
return 1;
|
2010-04-29 16:09:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2010-05-11 10:29:38 +00:00
|
|
|
static void kvm_cpu_vmxon(u64 addr)
|
|
|
|
{
|
|
|
|
asm volatile (ASM_VMX_VMXON_RAX
|
|
|
|
: : "a"(&addr), "m"(addr)
|
|
|
|
: "memory", "cc");
|
|
|
|
}
|
|
|
|
|
2014-08-28 13:13:03 +00:00
|
|
|
static int hardware_enable(void)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
int cpu = raw_smp_processor_id();
|
|
|
|
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
|
2010-04-29 16:09:01 +00:00
|
|
|
u64 old, test_bits;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2014-10-24 22:58:08 +00:00
|
|
|
if (cr4_read_shadow() & X86_CR4_VMXE)
|
2009-09-15 09:37:46 +00:00
|
|
|
return -EBUSY;
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
|
2012-12-06 15:43:34 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now we can enable the vmclear operation in kdump
|
|
|
|
* since the loaded_vmcss_on_cpu list on this cpu
|
|
|
|
* has been initialized.
|
|
|
|
*
|
|
|
|
* Though the cpu is not in VMX operation now, there
|
|
|
|
* is no problem to enable the vmclear operation
|
|
|
|
* for the loaded_vmcss_on_cpu list is empty!
|
|
|
|
*/
|
|
|
|
crash_enable_local_vmclear(cpu);
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
|
2010-04-29 16:09:01 +00:00
|
|
|
|
|
|
|
test_bits = FEATURE_CONTROL_LOCKED;
|
|
|
|
test_bits |= FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
|
|
|
if (tboot_enabled())
|
|
|
|
test_bits |= FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX;
|
|
|
|
|
|
|
|
if ((old & test_bits) != test_bits) {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* enable and lock */
|
2010-04-29 16:09:01 +00:00
|
|
|
wrmsrl(MSR_IA32_FEATURE_CONTROL, old | test_bits);
|
|
|
|
}
|
2014-10-24 22:58:07 +00:00
|
|
|
cr4_set_bits(X86_CR4_VMXE);
|
2009-09-15 09:37:46 +00:00
|
|
|
|
2010-05-11 10:29:48 +00:00
|
|
|
if (vmm_exclusive) {
|
|
|
|
kvm_cpu_vmxon(phys_addr);
|
|
|
|
ept_sync_global();
|
|
|
|
}
|
2009-09-15 09:37:46 +00:00
|
|
|
|
x86: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-17 17:30:40 +00:00
|
|
|
native_store_gdt(this_cpu_ptr(&host_gdt));
|
2010-07-26 15:32:38 +00:00
|
|
|
|
2009-09-15 09:37:46 +00:00
|
|
|
return 0;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
static void vmclear_local_loaded_vmcss(void)
|
2008-05-13 13:22:47 +00:00
|
|
|
{
|
|
|
|
int cpu = raw_smp_processor_id();
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
struct loaded_vmcs *v, *n;
|
2008-05-13 13:22:47 +00:00
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
list_for_each_entry_safe(v, n, &per_cpu(loaded_vmcss_on_cpu, cpu),
|
|
|
|
loaded_vmcss_on_cpu_link)
|
|
|
|
__loaded_vmcs_clear(v);
|
2008-05-13 13:22:47 +00:00
|
|
|
}
|
|
|
|
|
2008-11-17 21:03:18 +00:00
|
|
|
|
|
|
|
/* Just like cpu_vmxoff(), but with the __kvm_handle_fault_on_reboot()
|
|
|
|
* tricks.
|
|
|
|
*/
|
|
|
|
static void kvm_cpu_vmxoff(void)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2008-05-13 10:23:38 +00:00
|
|
|
asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc");
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2014-08-28 13:13:03 +00:00
|
|
|
static void hardware_disable(void)
|
2008-11-17 21:03:18 +00:00
|
|
|
{
|
2010-05-11 10:29:48 +00:00
|
|
|
if (vmm_exclusive) {
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
vmclear_local_loaded_vmcss();
|
2010-05-11 10:29:48 +00:00
|
|
|
kvm_cpu_vmxoff();
|
|
|
|
}
|
2014-10-24 22:58:07 +00:00
|
|
|
cr4_clear_bits(X86_CR4_VMXE);
|
2008-11-17 21:03:18 +00:00
|
|
|
}
|
|
|
|
|
2007-07-29 08:07:42 +00:00
|
|
|
static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
|
2007-10-08 13:02:08 +00:00
|
|
|
u32 msr, u32 *result)
|
2007-07-29 08:07:42 +00:00
|
|
|
{
|
|
|
|
u32 vmx_msr_low, vmx_msr_high;
|
|
|
|
u32 ctl = ctl_min | ctl_opt;
|
|
|
|
|
|
|
|
rdmsr(msr, vmx_msr_low, vmx_msr_high);
|
|
|
|
|
|
|
|
ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */
|
|
|
|
ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */
|
|
|
|
|
|
|
|
/* Ensure minimum (required) set of control bits are supported. */
|
|
|
|
if (ctl_min & ~ctl)
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
2007-07-29 08:07:42 +00:00
|
|
|
|
|
|
|
*result = ctl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-21 10:54:20 +00:00
|
|
|
static __init bool allow_1_setting(u32 msr, u32 ctl)
|
|
|
|
{
|
|
|
|
u32 vmx_msr_low, vmx_msr_high;
|
|
|
|
|
|
|
|
rdmsr(msr, vmx_msr_low, vmx_msr_high);
|
|
|
|
return vmx_msr_high & ctl;
|
|
|
|
}
|
|
|
|
|
2007-07-31 11:23:01 +00:00
|
|
|
static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
u32 vmx_msr_low, vmx_msr_high;
|
2008-04-25 02:13:16 +00:00
|
|
|
u32 min, opt, min2, opt2;
|
2007-07-29 08:07:42 +00:00
|
|
|
u32 _pin_based_exec_control = 0;
|
|
|
|
u32 _cpu_based_exec_control = 0;
|
2007-10-29 01:40:42 +00:00
|
|
|
u32 _cpu_based_2nd_exec_control = 0;
|
2007-07-29 08:07:42 +00:00
|
|
|
u32 _vmexit_control = 0;
|
|
|
|
u32 _vmentry_control = 0;
|
|
|
|
|
2012-02-07 17:49:20 +00:00
|
|
|
min = CPU_BASED_HLT_EXITING |
|
2007-07-29 08:07:42 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
CPU_BASED_CR8_LOAD_EXITING |
|
|
|
|
CPU_BASED_CR8_STORE_EXITING |
|
|
|
|
#endif
|
2008-04-25 02:13:16 +00:00
|
|
|
CPU_BASED_CR3_LOAD_EXITING |
|
|
|
|
CPU_BASED_CR3_STORE_EXITING |
|
2007-07-29 08:07:42 +00:00
|
|
|
CPU_BASED_USE_IO_BITMAPS |
|
|
|
|
CPU_BASED_MOV_DR_EXITING |
|
2008-09-23 16:18:35 +00:00
|
|
|
CPU_BASED_USE_TSC_OFFSETING |
|
2009-12-15 05:29:54 +00:00
|
|
|
CPU_BASED_MWAIT_EXITING |
|
|
|
|
CPU_BASED_MONITOR_EXITING |
|
2011-11-10 12:57:25 +00:00
|
|
|
CPU_BASED_INVLPG_EXITING |
|
|
|
|
CPU_BASED_RDPMC_EXITING;
|
2010-12-06 16:53:38 +00:00
|
|
|
|
2007-10-29 01:40:42 +00:00
|
|
|
opt = CPU_BASED_TPR_SHADOW |
|
2008-03-28 05:18:56 +00:00
|
|
|
CPU_BASED_USE_MSR_BITMAPS |
|
2007-10-29 01:40:42 +00:00
|
|
|
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
|
2007-07-29 08:07:42 +00:00
|
|
|
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
|
|
|
|
&_cpu_based_exec_control) < 0)
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
2007-09-12 10:03:11 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
if ((_cpu_based_exec_control & CPU_BASED_TPR_SHADOW))
|
|
|
|
_cpu_based_exec_control &= ~CPU_BASED_CR8_LOAD_EXITING &
|
|
|
|
~CPU_BASED_CR8_STORE_EXITING;
|
|
|
|
#endif
|
2007-10-29 01:40:42 +00:00
|
|
|
if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) {
|
2008-04-25 02:13:16 +00:00
|
|
|
min2 = 0;
|
|
|
|
opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
|
2013-01-25 02:18:50 +00:00
|
|
|
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
|
2008-01-17 07:14:33 +00:00
|
|
|
SECONDARY_EXEC_WBINVD_EXITING |
|
2008-04-25 02:13:16 +00:00
|
|
|
SECONDARY_EXEC_ENABLE_VPID |
|
2009-06-08 18:34:16 +00:00
|
|
|
SECONDARY_EXEC_ENABLE_EPT |
|
2009-10-09 10:03:20 +00:00
|
|
|
SECONDARY_EXEC_UNRESTRICTED_GUEST |
|
2009-12-18 08:48:47 +00:00
|
|
|
SECONDARY_EXEC_PAUSE_LOOP_EXITING |
|
2012-07-02 01:18:48 +00:00
|
|
|
SECONDARY_EXEC_RDTSCP |
|
2013-01-25 02:18:49 +00:00
|
|
|
SECONDARY_EXEC_ENABLE_INVPCID |
|
2013-01-25 02:18:51 +00:00
|
|
|
SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
2013-04-18 11:35:25 +00:00
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
|
2014-12-02 11:14:59 +00:00
|
|
|
SECONDARY_EXEC_SHADOW_VMCS |
|
2015-01-28 02:54:28 +00:00
|
|
|
SECONDARY_EXEC_XSAVES |
|
|
|
|
SECONDARY_EXEC_ENABLE_PML;
|
2008-04-25 02:13:16 +00:00
|
|
|
if (adjust_vmx_controls(min2, opt2,
|
|
|
|
MSR_IA32_VMX_PROCBASED_CTLS2,
|
2007-10-29 01:40:42 +00:00
|
|
|
&_cpu_based_2nd_exec_control) < 0)
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
#ifndef CONFIG_X86_64
|
|
|
|
if (!(_cpu_based_2nd_exec_control &
|
|
|
|
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
|
|
|
|
_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
|
|
|
|
#endif
|
2013-01-25 02:18:49 +00:00
|
|
|
|
|
|
|
if (!(_cpu_based_exec_control & CPU_BASED_TPR_SHADOW))
|
|
|
|
_cpu_based_2nd_exec_control &= ~(
|
2013-01-25 02:18:50 +00:00
|
|
|
SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
2013-01-25 02:18:51 +00:00
|
|
|
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
|
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
|
2013-01-25 02:18:49 +00:00
|
|
|
|
2008-04-25 02:13:16 +00:00
|
|
|
if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
|
2008-09-23 16:18:35 +00:00
|
|
|
/* CR3 accesses and invlpg don't need to cause VM Exits when EPT
|
|
|
|
enabled */
|
2009-08-27 15:41:30 +00:00
|
|
|
_cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING |
|
|
|
|
CPU_BASED_CR3_STORE_EXITING |
|
|
|
|
CPU_BASED_INVLPG_EXITING);
|
2008-04-25 02:13:16 +00:00
|
|
|
rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
|
|
|
|
vmx_capability.ept, vmx_capability.vpid);
|
|
|
|
}
|
2007-07-29 08:07:42 +00:00
|
|
|
|
2014-02-21 09:32:27 +00:00
|
|
|
min = VM_EXIT_SAVE_DEBUG_CONTROLS;
|
2007-07-29 08:07:42 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
min |= VM_EXIT_HOST_ADDR_SPACE_SIZE;
|
|
|
|
#endif
|
2013-04-11 11:25:10 +00:00
|
|
|
opt = VM_EXIT_SAVE_IA32_PAT | VM_EXIT_LOAD_IA32_PAT |
|
2014-02-24 10:55:46 +00:00
|
|
|
VM_EXIT_ACK_INTR_ON_EXIT | VM_EXIT_CLEAR_BNDCFGS;
|
2007-07-29 08:07:42 +00:00
|
|
|
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS,
|
|
|
|
&_vmexit_control) < 0)
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
2007-07-29 08:07:42 +00:00
|
|
|
|
2013-04-11 11:25:12 +00:00
|
|
|
min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
|
|
|
|
opt = PIN_BASED_VIRTUAL_NMIS | PIN_BASED_POSTED_INTR;
|
|
|
|
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS,
|
|
|
|
&_pin_based_exec_control) < 0)
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
if (!(_cpu_based_2nd_exec_control &
|
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY) ||
|
|
|
|
!(_vmexit_control & VM_EXIT_ACK_INTR_ON_EXIT))
|
|
|
|
_pin_based_exec_control &= ~PIN_BASED_POSTED_INTR;
|
|
|
|
|
2014-02-21 09:55:44 +00:00
|
|
|
min = VM_ENTRY_LOAD_DEBUG_CONTROLS;
|
2014-02-24 10:55:46 +00:00
|
|
|
opt = VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS;
|
2007-07-29 08:07:42 +00:00
|
|
|
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS,
|
|
|
|
&_vmentry_control) < 0)
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2006-12-30 00:49:54 +00:00
|
|
|
rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
|
2007-07-29 08:07:42 +00:00
|
|
|
|
|
|
|
/* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
|
|
|
|
if ((vmx_msr_high & 0x1fff) > PAGE_SIZE)
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
2007-07-29 08:07:42 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
/* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */
|
|
|
|
if (vmx_msr_high & (1u<<16))
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
2007-07-29 08:07:42 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Require Write-Back (WB) memory type for VMCS accesses. */
|
|
|
|
if (((vmx_msr_high >> 18) & 15) != 6)
|
2007-07-31 11:23:01 +00:00
|
|
|
return -EIO;
|
2007-07-29 08:07:42 +00:00
|
|
|
|
2007-07-31 11:23:01 +00:00
|
|
|
vmcs_conf->size = vmx_msr_high & 0x1fff;
|
|
|
|
vmcs_conf->order = get_order(vmcs_config.size);
|
|
|
|
vmcs_conf->revision_id = vmx_msr_low;
|
2007-07-29 08:07:42 +00:00
|
|
|
|
2007-07-31 11:23:01 +00:00
|
|
|
vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control;
|
|
|
|
vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control;
|
2007-10-29 01:40:42 +00:00
|
|
|
vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control;
|
2007-07-31 11:23:01 +00:00
|
|
|
vmcs_conf->vmexit_ctrl = _vmexit_control;
|
|
|
|
vmcs_conf->vmentry_ctrl = _vmentry_control;
|
2007-07-29 08:07:42 +00:00
|
|
|
|
2010-12-21 10:54:20 +00:00
|
|
|
cpu_has_load_ia32_efer =
|
|
|
|
allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS,
|
|
|
|
VM_ENTRY_LOAD_IA32_EFER)
|
|
|
|
&& allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
|
|
|
|
VM_EXIT_LOAD_IA32_EFER);
|
|
|
|
|
2011-10-05 12:01:22 +00:00
|
|
|
cpu_has_load_perf_global_ctrl =
|
|
|
|
allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS,
|
|
|
|
VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
|
|
|
|
&& allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
|
|
|
|
VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some cpus support VM_ENTRY_(LOAD|SAVE)_IA32_PERF_GLOBAL_CTRL
|
|
|
|
* but due to arrata below it can't be used. Workaround is to use
|
|
|
|
* msr load mechanism to switch IA32_PERF_GLOBAL_CTRL.
|
|
|
|
*
|
|
|
|
* VM Exit May Incorrectly Clear IA32_PERF_GLOBAL_CTRL [34:32]
|
|
|
|
*
|
|
|
|
* AAK155 (model 26)
|
|
|
|
* AAP115 (model 30)
|
|
|
|
* AAT100 (model 37)
|
|
|
|
* BC86,AAY89,BD102 (model 44)
|
|
|
|
* BA97 (model 46)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
if (cpu_has_load_perf_global_ctrl && boot_cpu_data.x86 == 0x6) {
|
|
|
|
switch (boot_cpu_data.x86_model) {
|
|
|
|
case 26:
|
|
|
|
case 30:
|
|
|
|
case 37:
|
|
|
|
case 44:
|
|
|
|
case 46:
|
|
|
|
cpu_has_load_perf_global_ctrl = false;
|
|
|
|
printk_once(KERN_WARNING"kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
|
|
|
|
"does not work properly. Using workaround\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-02 11:14:59 +00:00
|
|
|
if (cpu_has_xsaves)
|
|
|
|
rdmsrl(MSR_IA32_XSS, host_xss);
|
|
|
|
|
2007-07-29 08:07:42 +00:00
|
|
|
return 0;
|
2006-12-30 00:49:54 +00:00
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
static struct vmcs *alloc_vmcs_cpu(int cpu)
|
|
|
|
{
|
|
|
|
int node = cpu_to_node(cpu);
|
|
|
|
struct page *pages;
|
|
|
|
struct vmcs *vmcs;
|
|
|
|
|
mm: rename alloc_pages_exact_node() to __alloc_pages_node()
alloc_pages_exact_node() was introduced in commit 6484eb3e2a81 ("page
allocator: do not check NUMA node ID when the caller knows the node is
valid") as an optimized variant of alloc_pages_node(), that doesn't
fallback to current node for nid == NUMA_NO_NODE. Unfortunately the
name of the function can easily suggest that the allocation is
restricted to the given node and fails otherwise. In truth, the node is
only preferred, unless __GFP_THISNODE is passed among the gfp flags.
The misleading name has lead to mistakes in the past, see for example
commits 5265047ac301 ("mm, thp: really limit transparent hugepage
allocation to local node") and b360edb43f8e ("mm, mempolicy:
migrate_to_node should only migrate to node").
Another issue with the name is that there's a family of
alloc_pages_exact*() functions where 'exact' means exact size (instead
of page order), which leads to more confusion.
To prevent further mistakes, this patch effectively renames
alloc_pages_exact_node() to __alloc_pages_node() to better convey that
it's an optimized variant of alloc_pages_node() not intended for general
usage. Both functions get described in comments.
It has been also considered to really provide a convenience function for
allocations restricted to a node, but the major opinion seems to be that
__GFP_THISNODE already provides that functionality and we shouldn't
duplicate the API needlessly. The number of users would be small
anyway.
Existing callers of alloc_pages_exact_node() are simply converted to
call __alloc_pages_node(), with the exception of sba_alloc_coherent()
which open-codes the check for NUMA_NO_NODE, so it is converted to use
alloc_pages_node() instead. This means it no longer performs some
VM_BUG_ON checks, and since the current check for nid in
alloc_pages_node() uses a 'nid < 0' comparison (which includes
NUMA_NO_NODE), it may hide wrong values which would be previously
exposed.
Both differences will be rectified by the next patch.
To sum up, this patch makes no functional changes, except temporarily
hiding potentially buggy callers. Restricting the checks in
alloc_pages_node() is left for the next patch which can in turn expose
more existing buggy callers.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Robin Holt <robinmholt@gmail.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Christoph Lameter <cl@linux.com>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Cc: Mel Gorman <mgorman@suse.de>
Cc: David Rientjes <rientjes@google.com>
Cc: Greg Thelen <gthelen@google.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Cliff Whickman <cpw@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-09-08 22:03:50 +00:00
|
|
|
pages = __alloc_pages_node(node, GFP_KERNEL, vmcs_config.order);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
if (!pages)
|
|
|
|
return NULL;
|
|
|
|
vmcs = page_address(pages);
|
2007-07-29 08:07:42 +00:00
|
|
|
memset(vmcs, 0, vmcs_config.size);
|
|
|
|
vmcs->revision_id = vmcs_config.revision_id; /* vmcs revision id */
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return vmcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct vmcs *alloc_vmcs(void)
|
|
|
|
{
|
2007-01-06 00:36:23 +00:00
|
|
|
return alloc_vmcs_cpu(raw_smp_processor_id());
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void free_vmcs(struct vmcs *vmcs)
|
|
|
|
{
|
2007-07-29 08:07:42 +00:00
|
|
|
free_pages((unsigned long)vmcs, vmcs_config.order);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
/*
|
|
|
|
* Free a VMCS, but before that VMCLEAR it on the CPU where it was last loaded
|
|
|
|
*/
|
|
|
|
static void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
|
|
|
|
{
|
|
|
|
if (!loaded_vmcs->vmcs)
|
|
|
|
return;
|
|
|
|
loaded_vmcs_clear(loaded_vmcs);
|
|
|
|
free_vmcs(loaded_vmcs->vmcs);
|
|
|
|
loaded_vmcs->vmcs = NULL;
|
|
|
|
}
|
|
|
|
|
2007-06-01 07:47:13 +00:00
|
|
|
static void free_kvm_area(void)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
int cpu;
|
|
|
|
|
2009-09-29 21:38:37 +00:00
|
|
|
for_each_possible_cpu(cpu) {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
free_vmcs(per_cpu(vmxarea, cpu));
|
2009-09-29 21:38:37 +00:00
|
|
|
per_cpu(vmxarea, cpu) = NULL;
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2014-04-21 19:20:14 +00:00
|
|
|
static void init_vmcs_shadow_fields(void)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
/* No checks for read only fields yet */
|
|
|
|
|
|
|
|
for (i = j = 0; i < max_shadow_read_write_fields; i++) {
|
|
|
|
switch (shadow_read_write_fields[i]) {
|
|
|
|
case GUEST_BNDCFGS:
|
|
|
|
if (!vmx_mpx_supported())
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j < i)
|
|
|
|
shadow_read_write_fields[j] =
|
|
|
|
shadow_read_write_fields[i];
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
max_shadow_read_write_fields = j;
|
|
|
|
|
|
|
|
/* shadowed fields guest access without vmexit */
|
|
|
|
for (i = 0; i < max_shadow_read_write_fields; i++) {
|
|
|
|
clear_bit(shadow_read_write_fields[i],
|
|
|
|
vmx_vmwrite_bitmap);
|
|
|
|
clear_bit(shadow_read_write_fields[i],
|
|
|
|
vmx_vmread_bitmap);
|
|
|
|
}
|
|
|
|
for (i = 0; i < max_shadow_read_only_fields; i++)
|
|
|
|
clear_bit(shadow_read_only_fields[i],
|
|
|
|
vmx_vmread_bitmap);
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static __init int alloc_kvm_area(void)
|
|
|
|
{
|
|
|
|
int cpu;
|
|
|
|
|
2009-09-29 21:38:37 +00:00
|
|
|
for_each_possible_cpu(cpu) {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
struct vmcs *vmcs;
|
|
|
|
|
|
|
|
vmcs = alloc_vmcs_cpu(cpu);
|
|
|
|
if (!vmcs) {
|
|
|
|
free_kvm_area();
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
per_cpu(vmxarea, cpu) = vmcs;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-21 13:36:49 +00:00
|
|
|
static bool emulation_required(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return emulate_invalid_guest_state && !guest_state_valid(vcpu);
|
|
|
|
}
|
|
|
|
|
2013-01-21 13:36:47 +00:00
|
|
|
static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg,
|
2012-12-20 14:57:45 +00:00
|
|
|
struct kvm_segment *save)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2012-12-20 14:57:45 +00:00
|
|
|
if (!emulate_invalid_guest_state) {
|
|
|
|
/*
|
|
|
|
* CS and SS RPL should be equal during guest entry according
|
|
|
|
* to VMX spec, but in reality it is not always so. Since vcpu
|
|
|
|
* is in the middle of the transition from real mode to
|
|
|
|
* protected mode it is safe to assume that RPL 0 is a good
|
|
|
|
* default value.
|
|
|
|
*/
|
|
|
|
if (seg == VCPU_SREG_CS || seg == VCPU_SREG_SS)
|
2015-03-29 13:33:04 +00:00
|
|
|
save->selector &= ~SEGMENT_RPL_MASK;
|
|
|
|
save->dpl = save->selector & SEGMENT_RPL_MASK;
|
2012-12-20 14:57:45 +00:00
|
|
|
save->s = 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
2012-12-20 14:57:45 +00:00
|
|
|
vmx_set_segment(vcpu, save, seg);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void enter_pmode(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
2008-08-17 13:42:16 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2012-12-20 14:57:45 +00:00
|
|
|
/*
|
|
|
|
* Update real mode segment cache. It may be not up-to-date if sement
|
|
|
|
* register was written while vcpu was in a guest mode.
|
|
|
|
*/
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_FS], VCPU_SREG_FS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_GS], VCPU_SREG_GS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_SS], VCPU_SREG_SS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_CS], VCPU_SREG_CS);
|
|
|
|
|
2009-06-09 11:10:45 +00:00
|
|
|
vmx->rmode.vm86_active = 0;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
|
|
|
|
2012-08-21 14:07:00 +00:00
|
|
|
vmx_set_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
flags = vmcs_readl(GUEST_RFLAGS);
|
2010-04-08 15:19:35 +00:00
|
|
|
flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
|
|
|
|
flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_writel(GUEST_RFLAGS, flags);
|
|
|
|
|
2007-07-17 13:34:16 +00:00
|
|
|
vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
|
|
|
|
(vmcs_readl(CR4_READ_SHADOW) & X86_CR4_VME));
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
update_exception_bitmap(vcpu);
|
|
|
|
|
2013-01-21 13:36:47 +00:00
|
|
|
fix_pmode_seg(vcpu, VCPU_SREG_CS, &vmx->rmode.segs[VCPU_SREG_CS]);
|
|
|
|
fix_pmode_seg(vcpu, VCPU_SREG_SS, &vmx->rmode.segs[VCPU_SREG_SS]);
|
|
|
|
fix_pmode_seg(vcpu, VCPU_SREG_ES, &vmx->rmode.segs[VCPU_SREG_ES]);
|
|
|
|
fix_pmode_seg(vcpu, VCPU_SREG_DS, &vmx->rmode.segs[VCPU_SREG_DS]);
|
|
|
|
fix_pmode_seg(vcpu, VCPU_SREG_FS, &vmx->rmode.segs[VCPU_SREG_FS]);
|
|
|
|
fix_pmode_seg(vcpu, VCPU_SREG_GS, &vmx->rmode.segs[VCPU_SREG_GS]);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2012-08-21 14:07:00 +00:00
|
|
|
static void fix_rmode_seg(int seg, struct kvm_segment *save)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2012-08-29 23:30:19 +00:00
|
|
|
const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
|
2012-12-20 14:57:45 +00:00
|
|
|
struct kvm_segment var = *save;
|
|
|
|
|
|
|
|
var.dpl = 0x3;
|
|
|
|
if (seg == VCPU_SREG_CS)
|
|
|
|
var.type = 0x3;
|
|
|
|
|
|
|
|
if (!emulate_invalid_guest_state) {
|
|
|
|
var.selector = var.base >> 4;
|
|
|
|
var.base = var.base & 0xffff0;
|
|
|
|
var.limit = 0xffff;
|
|
|
|
var.g = 0;
|
|
|
|
var.db = 0;
|
|
|
|
var.present = 1;
|
|
|
|
var.s = 1;
|
|
|
|
var.l = 0;
|
|
|
|
var.unusable = 0;
|
|
|
|
var.type = 0x3;
|
|
|
|
var.avl = 0;
|
|
|
|
if (save->base & 0xf)
|
|
|
|
printk_once(KERN_WARNING "kvm: segment base is not "
|
|
|
|
"paragraph aligned when entering "
|
|
|
|
"protected mode (seg=%d)", seg);
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2012-12-20 14:57:45 +00:00
|
|
|
vmcs_write16(sf->selector, var.selector);
|
|
|
|
vmcs_write32(sf->base, var.base);
|
|
|
|
vmcs_write32(sf->limit, var.limit);
|
|
|
|
vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(&var));
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void enter_rmode(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
2008-08-17 13:42:16 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2012-08-21 14:07:00 +00:00
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_FS], VCPU_SREG_FS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_GS], VCPU_SREG_GS);
|
2012-12-12 17:10:51 +00:00
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_SS], VCPU_SREG_SS);
|
|
|
|
vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_CS], VCPU_SREG_CS);
|
2012-08-21 14:07:00 +00:00
|
|
|
|
2009-06-09 11:10:45 +00:00
|
|
|
vmx->rmode.vm86_active = 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2011-03-13 10:34:27 +00:00
|
|
|
/*
|
|
|
|
* Very old userspace does not call KVM_SET_TSS_ADDR before entering
|
2013-03-15 07:38:56 +00:00
|
|
|
* vcpu. Warn the user that an update is overdue.
|
2011-03-13 10:34:27 +00:00
|
|
|
*/
|
2013-03-15 07:38:56 +00:00
|
|
|
if (!vcpu->kvm->arch.tss_addr)
|
2011-03-13 10:34:27 +00:00
|
|
|
printk_once(KERN_WARNING "kvm: KVM_SET_TSS_ADDR need to be "
|
|
|
|
"called before entering vcpu\n");
|
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
|
|
|
|
2013-03-15 07:38:56 +00:00
|
|
|
vmcs_writel(GUEST_TR_BASE, vcpu->kvm->arch.tss_addr);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
|
|
|
|
vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
|
|
|
|
|
|
|
|
flags = vmcs_readl(GUEST_RFLAGS);
|
2010-04-08 15:19:35 +00:00
|
|
|
vmx->rmode.save_rflags = flags;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2008-01-30 12:31:27 +00:00
|
|
|
flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
vmcs_writel(GUEST_RFLAGS, flags);
|
2007-07-17 13:34:16 +00:00
|
|
|
vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | X86_CR4_VME);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
update_exception_bitmap(vcpu);
|
|
|
|
|
2012-12-20 14:57:45 +00:00
|
|
|
fix_rmode_seg(VCPU_SREG_SS, &vmx->rmode.segs[VCPU_SREG_SS]);
|
|
|
|
fix_rmode_seg(VCPU_SREG_CS, &vmx->rmode.segs[VCPU_SREG_CS]);
|
|
|
|
fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.segs[VCPU_SREG_ES]);
|
|
|
|
fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.segs[VCPU_SREG_DS]);
|
|
|
|
fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.segs[VCPU_SREG_GS]);
|
|
|
|
fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.segs[VCPU_SREG_FS]);
|
2012-05-31 11:49:22 +00:00
|
|
|
|
2007-10-10 06:26:45 +00:00
|
|
|
kvm_mmu_reset_context(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 17:23:37 +00:00
|
|
|
static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-09-07 08:14:12 +00:00
|
|
|
struct shared_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
|
|
|
|
|
|
|
|
if (!msr)
|
|
|
|
return;
|
2009-02-20 17:23:37 +00:00
|
|
|
|
2009-09-06 12:55:37 +00:00
|
|
|
/*
|
|
|
|
* Force kernel_gs_base reloading before EFER changes, as control
|
|
|
|
* of this msr depends on is_long_mode().
|
|
|
|
*/
|
|
|
|
vmx_load_host_state(to_vmx(vcpu));
|
2010-01-21 13:31:50 +00:00
|
|
|
vcpu->arch.efer = efer;
|
2009-02-20 17:23:37 +00:00
|
|
|
if (efer & EFER_LMA) {
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_setbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE);
|
2009-02-20 17:23:37 +00:00
|
|
|
msr->data = efer;
|
|
|
|
} else {
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_clearbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE);
|
2009-02-20 17:23:37 +00:00
|
|
|
|
|
|
|
msr->data = efer & ~EFER_LME;
|
|
|
|
}
|
|
|
|
setup_msrs(vmx);
|
|
|
|
}
|
|
|
|
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
static void enter_lmode(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u32 guest_tr_ar;
|
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(to_vmx(vcpu));
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
guest_tr_ar = vmcs_read32(GUEST_TR_AR_BYTES);
|
2015-08-13 20:18:48 +00:00
|
|
|
if ((guest_tr_ar & VMX_AR_TYPE_MASK) != VMX_AR_TYPE_BUSY_64_TSS) {
|
2011-09-12 09:26:22 +00:00
|
|
|
pr_debug_ratelimited("%s: tss fixup for long mode. \n",
|
|
|
|
__func__);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_write32(GUEST_TR_AR_BYTES,
|
2015-08-13 20:18:48 +00:00
|
|
|
(guest_tr_ar & ~VMX_AR_TYPE_MASK)
|
|
|
|
| VMX_AR_TYPE_BUSY_64_TSS);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
2010-07-06 08:30:49 +00:00
|
|
|
vmx_set_efer(vcpu, vcpu->arch.efer | EFER_LMA);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void exit_lmode(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_clearbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE);
|
2010-07-06 08:30:49 +00:00
|
|
|
vmx_set_efer(vcpu, vcpu->arch.efer & ~EFER_LMA);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2010-06-07 02:32:29 +00:00
|
|
|
vpid_sync_context(to_vmx(vcpu));
|
2010-07-03 08:02:42 +00:00
|
|
|
if (enable_ept) {
|
|
|
|
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
|
|
|
|
return;
|
2008-07-06 11:16:51 +00:00
|
|
|
ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa));
|
2010-07-03 08:02:42 +00:00
|
|
|
}
|
2008-01-17 07:14:33 +00:00
|
|
|
}
|
|
|
|
|
2009-12-29 16:43:06 +00:00
|
|
|
static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
|
|
|
|
|
|
|
|
vcpu->arch.cr0 &= ~cr0_guest_owned_bits;
|
|
|
|
vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits;
|
|
|
|
}
|
|
|
|
|
2010-12-05 16:56:11 +00:00
|
|
|
static void vmx_decache_cr3(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
if (enable_ept && is_paging(vcpu))
|
|
|
|
vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
|
|
|
|
__set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
|
|
|
|
}
|
|
|
|
|
2007-04-27 06:29:21 +00:00
|
|
|
static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
|
2007-01-06 00:36:38 +00:00
|
|
|
{
|
2009-12-07 10:16:48 +00:00
|
|
|
ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits;
|
|
|
|
|
|
|
|
vcpu->arch.cr4 &= ~cr4_guest_owned_bits;
|
|
|
|
vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & cr4_guest_owned_bits;
|
2007-01-06 00:36:38 +00:00
|
|
|
}
|
|
|
|
|
2008-04-28 04:24:45 +00:00
|
|
|
static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2013-10-09 16:13:19 +00:00
|
|
|
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
|
|
|
|
|
2009-05-31 19:58:47 +00:00
|
|
|
if (!test_bit(VCPU_EXREG_PDPTR,
|
|
|
|
(unsigned long *)&vcpu->arch.regs_dirty))
|
|
|
|
return;
|
|
|
|
|
2008-04-28 04:24:45 +00:00
|
|
|
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
|
2013-10-09 16:13:19 +00:00
|
|
|
vmcs_write64(GUEST_PDPTR0, mmu->pdptrs[0]);
|
|
|
|
vmcs_write64(GUEST_PDPTR1, mmu->pdptrs[1]);
|
|
|
|
vmcs_write64(GUEST_PDPTR2, mmu->pdptrs[2]);
|
|
|
|
vmcs_write64(GUEST_PDPTR3, mmu->pdptrs[3]);
|
2008-04-28 04:24:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-31 15:41:29 +00:00
|
|
|
static void ept_save_pdptrs(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2013-10-09 16:13:19 +00:00
|
|
|
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
|
|
|
|
|
2009-05-31 15:41:29 +00:00
|
|
|
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
|
2013-10-09 16:13:19 +00:00
|
|
|
mmu->pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
|
|
|
|
mmu->pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
|
|
|
|
mmu->pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
|
|
|
|
mmu->pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
|
2009-05-31 15:41:29 +00:00
|
|
|
}
|
2009-05-31 19:58:47 +00:00
|
|
|
|
|
|
|
__set_bit(VCPU_EXREG_PDPTR,
|
|
|
|
(unsigned long *)&vcpu->arch.regs_avail);
|
|
|
|
__set_bit(VCPU_EXREG_PDPTR,
|
|
|
|
(unsigned long *)&vcpu->arch.regs_dirty);
|
2009-05-31 15:41:29 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:03:24 +00:00
|
|
|
static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
|
2008-04-28 04:24:45 +00:00
|
|
|
|
|
|
|
static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
|
|
|
|
unsigned long cr0,
|
|
|
|
struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2011-06-06 17:27:47 +00:00
|
|
|
if (!test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail))
|
|
|
|
vmx_decache_cr3(vcpu);
|
2008-04-28 04:24:45 +00:00
|
|
|
if (!(cr0 & X86_CR0_PG)) {
|
|
|
|
/* From paging/starting to nonpaging */
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
|
2008-06-18 06:43:38 +00:00
|
|
|
vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) |
|
2008-04-28 04:24:45 +00:00
|
|
|
(CPU_BASED_CR3_LOAD_EXITING |
|
|
|
|
CPU_BASED_CR3_STORE_EXITING));
|
|
|
|
vcpu->arch.cr0 = cr0;
|
2009-12-07 10:16:48 +00:00
|
|
|
vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
|
2008-04-28 04:24:45 +00:00
|
|
|
} else if (!is_paging(vcpu)) {
|
|
|
|
/* From nonpaging to paging */
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
|
2008-06-18 06:43:38 +00:00
|
|
|
vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) &
|
2008-04-28 04:24:45 +00:00
|
|
|
~(CPU_BASED_CR3_LOAD_EXITING |
|
|
|
|
CPU_BASED_CR3_STORE_EXITING));
|
|
|
|
vcpu->arch.cr0 = cr0;
|
2009-12-07 10:16:48 +00:00
|
|
|
vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
|
2008-04-28 04:24:45 +00:00
|
|
|
}
|
2009-08-19 01:52:18 +00:00
|
|
|
|
|
|
|
if (!(cr0 & X86_CR0_WP))
|
|
|
|
*hw_cr0 &= ~X86_CR0_WP;
|
2008-04-28 04:24:45 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
|
|
|
{
|
2009-06-09 11:10:45 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-06-08 18:34:16 +00:00
|
|
|
unsigned long hw_cr0;
|
|
|
|
|
2013-02-04 14:00:28 +00:00
|
|
|
hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK);
|
2009-06-08 18:34:16 +00:00
|
|
|
if (enable_unrestricted_guest)
|
2013-02-04 14:00:28 +00:00
|
|
|
hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
|
2013-01-21 13:36:45 +00:00
|
|
|
else {
|
2013-02-04 14:00:28 +00:00
|
|
|
hw_cr0 |= KVM_VM_CR0_ALWAYS_ON;
|
2008-04-28 04:24:45 +00:00
|
|
|
|
2013-01-21 13:36:45 +00:00
|
|
|
if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
|
|
|
|
enter_pmode(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2013-01-21 13:36:45 +00:00
|
|
|
if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE))
|
|
|
|
enter_rmode(vcpu);
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2010-01-21 13:31:50 +00:00
|
|
|
if (vcpu->arch.efer & EFER_LME) {
|
2007-07-17 13:19:08 +00:00
|
|
|
if (!is_paging(vcpu) && (cr0 & X86_CR0_PG))
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
enter_lmode(vcpu);
|
2007-07-17 13:19:08 +00:00
|
|
|
if (is_paging(vcpu) && !(cr0 & X86_CR0_PG))
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
exit_lmode(vcpu);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-03-23 16:26:32 +00:00
|
|
|
if (enable_ept)
|
2008-04-28 04:24:45 +00:00
|
|
|
ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
|
|
|
|
|
2009-12-30 10:40:26 +00:00
|
|
|
if (!vcpu->fpu_active)
|
2010-01-24 14:26:40 +00:00
|
|
|
hw_cr0 |= X86_CR0_TS | X86_CR0_MP;
|
2009-12-30 10:40:26 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_writel(CR0_READ_SHADOW, cr0);
|
2008-04-28 04:24:45 +00:00
|
|
|
vmcs_writel(GUEST_CR0, hw_cr0);
|
2007-12-13 15:50:52 +00:00
|
|
|
vcpu->arch.cr0 = cr0;
|
2013-01-21 13:36:49 +00:00
|
|
|
|
|
|
|
/* depends on vcpu->arch.cr0 to be set to a new value */
|
|
|
|
vmx->emulation_required = emulation_required(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2008-04-28 04:24:45 +00:00
|
|
|
static u64 construct_eptp(unsigned long root_hpa)
|
|
|
|
{
|
|
|
|
u64 eptp;
|
|
|
|
|
|
|
|
/* TODO write the value reading from MSR */
|
|
|
|
eptp = VMX_EPT_DEFAULT_MT |
|
|
|
|
VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
|
2012-05-28 11:33:36 +00:00
|
|
|
if (enable_ept_ad_bits)
|
|
|
|
eptp |= VMX_EPT_AD_ENABLE_BIT;
|
2008-04-28 04:24:45 +00:00
|
|
|
eptp |= (root_hpa & PAGE_MASK);
|
|
|
|
|
|
|
|
return eptp;
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
|
|
|
|
{
|
2008-04-28 04:24:45 +00:00
|
|
|
unsigned long guest_cr3;
|
|
|
|
u64 eptp;
|
|
|
|
|
|
|
|
guest_cr3 = cr3;
|
2009-03-23 16:26:32 +00:00
|
|
|
if (enable_ept) {
|
2008-04-28 04:24:45 +00:00
|
|
|
eptp = construct_eptp(cr3);
|
|
|
|
vmcs_write64(EPT_POINTER, eptp);
|
2013-08-08 14:26:29 +00:00
|
|
|
if (is_paging(vcpu) || is_guest_mode(vcpu))
|
|
|
|
guest_cr3 = kvm_read_cr3(vcpu);
|
|
|
|
else
|
|
|
|
guest_cr3 = vcpu->kvm->arch.ept_identity_map_addr;
|
2009-10-26 18:48:33 +00:00
|
|
|
ept_load_pdptrs(vcpu);
|
2008-04-28 04:24:45 +00:00
|
|
|
}
|
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
vmx_flush_tlb(vcpu);
|
2008-04-28 04:24:45 +00:00
|
|
|
vmcs_writel(GUEST_CR3, guest_cr3);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:03:24 +00:00
|
|
|
static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2015-04-16 18:58:05 +00:00
|
|
|
/*
|
|
|
|
* Pass through host's Machine Check Enable value to hw_cr4, which
|
|
|
|
* is in force while we are in guest mode. Do not let guests control
|
|
|
|
* this bit, even if host CR4.MCE == 0.
|
|
|
|
*/
|
|
|
|
unsigned long hw_cr4 =
|
|
|
|
(cr4_read_shadow() & X86_CR4_MCE) |
|
|
|
|
(cr4 & ~X86_CR4_MCE) |
|
|
|
|
(to_vmx(vcpu)->rmode.vm86_active ?
|
|
|
|
KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
|
2008-04-28 04:24:45 +00:00
|
|
|
|
2011-05-25 20:03:24 +00:00
|
|
|
if (cr4 & X86_CR4_VMXE) {
|
|
|
|
/*
|
|
|
|
* To use VMXON (and later other VMX instructions), a guest
|
|
|
|
* must first be able to turn on cr4.VMXE (see handle_vmon()).
|
|
|
|
* So basically the check on whether to allow nested VMX
|
|
|
|
* is here.
|
|
|
|
*/
|
|
|
|
if (!nested_vmx_allowed(vcpu))
|
|
|
|
return 1;
|
2013-03-07 13:08:07 +00:00
|
|
|
}
|
|
|
|
if (to_vmx(vcpu)->nested.vmxon &&
|
|
|
|
((cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON))
|
2011-05-25 20:03:24 +00:00
|
|
|
return 1;
|
|
|
|
|
2007-12-13 15:50:52 +00:00
|
|
|
vcpu->arch.cr4 = cr4;
|
2009-12-08 10:14:42 +00:00
|
|
|
if (enable_ept) {
|
|
|
|
if (!is_paging(vcpu)) {
|
|
|
|
hw_cr4 &= ~X86_CR4_PAE;
|
|
|
|
hw_cr4 |= X86_CR4_PSE;
|
2013-02-04 03:50:43 +00:00
|
|
|
/*
|
2014-04-01 09:46:35 +00:00
|
|
|
* SMEP/SMAP is disabled if CPU is in non-paging mode
|
|
|
|
* in hardware. However KVM always uses paging mode to
|
2013-02-04 03:50:43 +00:00
|
|
|
* emulate guest non-paging mode with TDP.
|
2014-04-01 09:46:35 +00:00
|
|
|
* To emulate this behavior, SMEP/SMAP needs to be
|
|
|
|
* manually disabled when guest switches to non-paging
|
|
|
|
* mode.
|
2013-02-04 03:50:43 +00:00
|
|
|
*/
|
2014-04-01 09:46:35 +00:00
|
|
|
hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
|
2009-12-08 10:14:42 +00:00
|
|
|
} else if (!(cr4 & X86_CR4_PAE)) {
|
|
|
|
hw_cr4 &= ~X86_CR4_PAE;
|
|
|
|
}
|
|
|
|
}
|
2008-04-28 04:24:45 +00:00
|
|
|
|
|
|
|
vmcs_writel(CR4_READ_SHADOW, cr4);
|
|
|
|
vmcs_writel(GUEST_CR4, hw_cr4);
|
2011-05-25 20:03:24 +00:00
|
|
|
return 0;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_get_segment(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_segment *var, int seg)
|
|
|
|
{
|
2011-01-03 12:28:52 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
u32 ar;
|
|
|
|
|
2012-12-12 17:10:51 +00:00
|
|
|
if (vmx->rmode.vm86_active && seg != VCPU_SREG_LDTR) {
|
2012-08-21 14:07:00 +00:00
|
|
|
*var = vmx->rmode.segs[seg];
|
2011-01-03 12:28:52 +00:00
|
|
|
if (seg == VCPU_SREG_TR
|
2011-04-27 16:42:18 +00:00
|
|
|
|| var->selector == vmx_read_guest_seg_selector(vmx, seg))
|
2012-08-21 14:07:00 +00:00
|
|
|
return;
|
2012-08-21 14:07:08 +00:00
|
|
|
var->base = vmx_read_guest_seg_base(vmx, seg);
|
|
|
|
var->selector = vmx_read_guest_seg_selector(vmx, seg);
|
|
|
|
return;
|
2011-01-03 12:28:52 +00:00
|
|
|
}
|
2011-04-27 16:42:18 +00:00
|
|
|
var->base = vmx_read_guest_seg_base(vmx, seg);
|
|
|
|
var->limit = vmx_read_guest_seg_limit(vmx, seg);
|
|
|
|
var->selector = vmx_read_guest_seg_selector(vmx, seg);
|
|
|
|
ar = vmx_read_guest_seg_ar(vmx, seg);
|
2013-06-28 10:17:18 +00:00
|
|
|
var->unusable = (ar >> 16) & 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
var->type = ar & 15;
|
|
|
|
var->s = (ar >> 4) & 1;
|
|
|
|
var->dpl = (ar >> 5) & 3;
|
2013-06-28 10:17:18 +00:00
|
|
|
/*
|
|
|
|
* Some userspaces do not preserve unusable property. Since usable
|
|
|
|
* segment has to be present according to VMX spec we can use present
|
|
|
|
* property to amend userspace bug by making unusable segment always
|
|
|
|
* nonpresent. vmx_segment_access_rights() already marks nonpresent
|
|
|
|
* segment as unusable.
|
|
|
|
*/
|
|
|
|
var->present = !var->unusable;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
var->avl = (ar >> 12) & 1;
|
|
|
|
var->l = (ar >> 13) & 1;
|
|
|
|
var->db = (ar >> 14) & 1;
|
|
|
|
var->g = (ar >> 15) & 1;
|
|
|
|
}
|
|
|
|
|
2011-01-03 12:28:52 +00:00
|
|
|
static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
|
|
|
|
{
|
|
|
|
struct kvm_segment s;
|
|
|
|
|
|
|
|
if (to_vmx(vcpu)->rmode.vm86_active) {
|
|
|
|
vmx_get_segment(vcpu, &s, seg);
|
|
|
|
return s.base;
|
|
|
|
}
|
2011-04-27 16:42:18 +00:00
|
|
|
return vmx_read_guest_seg_base(to_vmx(vcpu), seg);
|
2011-01-03 12:28:52 +00:00
|
|
|
}
|
|
|
|
|
2013-01-07 21:27:06 +00:00
|
|
|
static int vmx_get_cpl(struct kvm_vcpu *vcpu)
|
2008-03-24 17:38:34 +00:00
|
|
|
{
|
2013-01-07 21:27:06 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
2014-05-14 07:39:49 +00:00
|
|
|
if (unlikely(vmx->rmode.vm86_active))
|
2008-03-24 17:38:34 +00:00
|
|
|
return 0;
|
2014-05-14 07:39:49 +00:00
|
|
|
else {
|
|
|
|
int ar = vmx_read_guest_seg_ar(vmx, VCPU_SREG_SS);
|
2015-08-13 20:18:48 +00:00
|
|
|
return VMX_AR_DPL(ar);
|
2011-03-07 13:26:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-07 07:55:37 +00:00
|
|
|
static u32 vmx_segment_access_rights(struct kvm_segment *var)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
|
|
|
u32 ar;
|
|
|
|
|
2012-06-07 14:06:10 +00:00
|
|
|
if (var->unusable || !var->present)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
ar = 1 << 16;
|
|
|
|
else {
|
|
|
|
ar = var->type & 15;
|
|
|
|
ar |= (var->s & 1) << 4;
|
|
|
|
ar |= (var->dpl & 3) << 5;
|
|
|
|
ar |= (var->present & 1) << 7;
|
|
|
|
ar |= (var->avl & 1) << 12;
|
|
|
|
ar |= (var->l & 1) << 13;
|
|
|
|
ar |= (var->db & 1) << 14;
|
|
|
|
ar |= (var->g & 1) << 15;
|
|
|
|
}
|
2007-05-07 07:55:37 +00:00
|
|
|
|
|
|
|
return ar;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_set_segment(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_segment *var, int seg)
|
|
|
|
{
|
2009-06-09 11:10:45 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2012-08-29 23:30:19 +00:00
|
|
|
const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
|
2007-05-07 07:55:37 +00:00
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
|
|
|
|
2012-12-12 17:10:54 +00:00
|
|
|
if (vmx->rmode.vm86_active && seg != VCPU_SREG_LDTR) {
|
|
|
|
vmx->rmode.segs[seg] = *var;
|
|
|
|
if (seg == VCPU_SREG_TR)
|
|
|
|
vmcs_write16(sf->selector, var->selector);
|
|
|
|
else if (var->s)
|
|
|
|
fix_rmode_seg(seg, &vmx->rmode.segs[seg]);
|
2012-12-20 14:57:45 +00:00
|
|
|
goto out;
|
2007-05-07 07:55:37 +00:00
|
|
|
}
|
2012-12-12 17:10:54 +00:00
|
|
|
|
2007-05-07 07:55:37 +00:00
|
|
|
vmcs_writel(sf->base, var->base);
|
|
|
|
vmcs_write32(sf->limit, var->limit);
|
|
|
|
vmcs_write16(sf->selector, var->selector);
|
2009-06-08 18:34:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Fix the "Accessed" bit in AR field of segment registers for older
|
|
|
|
* qemu binaries.
|
|
|
|
* IA32 arch specifies that at the time of processor reset the
|
|
|
|
* "Accessed" bit in the AR field of segment registers is 1. And qemu
|
2012-06-28 07:16:19 +00:00
|
|
|
* is setting it to 0 in the userland code. This causes invalid guest
|
2009-06-08 18:34:16 +00:00
|
|
|
* state vmexit when "unrestricted guest" mode is turned on.
|
|
|
|
* Fix for this setup issue in cpu_reset is being pushed in the qemu
|
|
|
|
* tree. Newer qemu binaries with that qemu fix would not need this
|
|
|
|
* kvm hack.
|
|
|
|
*/
|
|
|
|
if (enable_unrestricted_guest && (seg != VCPU_SREG_LDTR))
|
2012-12-12 17:10:55 +00:00
|
|
|
var->type |= 0x1; /* Accessed */
|
2009-06-08 18:34:16 +00:00
|
|
|
|
2012-12-12 17:10:55 +00:00
|
|
|
vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(var));
|
2012-12-20 14:57:45 +00:00
|
|
|
|
|
|
|
out:
|
2014-03-27 08:51:52 +00:00
|
|
|
vmx->emulation_required = emulation_required(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
|
|
|
|
{
|
2011-04-27 16:42:18 +00:00
|
|
|
u32 ar = vmx_read_guest_seg_ar(to_vmx(vcpu), VCPU_SREG_CS);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
*db = (ar >> 14) & 1;
|
|
|
|
*l = (ar >> 13) & 1;
|
|
|
|
}
|
|
|
|
|
2010-02-16 08:51:48 +00:00
|
|
|
static void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2010-02-16 08:51:48 +00:00
|
|
|
dt->size = vmcs_read32(GUEST_IDTR_LIMIT);
|
|
|
|
dt->address = vmcs_readl(GUEST_IDTR_BASE);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2010-02-16 08:51:48 +00:00
|
|
|
static void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2010-02-16 08:51:48 +00:00
|
|
|
vmcs_write32(GUEST_IDTR_LIMIT, dt->size);
|
|
|
|
vmcs_writel(GUEST_IDTR_BASE, dt->address);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2010-02-16 08:51:48 +00:00
|
|
|
static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2010-02-16 08:51:48 +00:00
|
|
|
dt->size = vmcs_read32(GUEST_GDTR_LIMIT);
|
|
|
|
dt->address = vmcs_readl(GUEST_GDTR_BASE);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2010-02-16 08:51:48 +00:00
|
|
|
static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2010-02-16 08:51:48 +00:00
|
|
|
vmcs_write32(GUEST_GDTR_LIMIT, dt->size);
|
|
|
|
vmcs_writel(GUEST_GDTR_BASE, dt->address);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2008-08-17 13:38:32 +00:00
|
|
|
static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg)
|
|
|
|
{
|
|
|
|
struct kvm_segment var;
|
|
|
|
u32 ar;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &var, seg);
|
2012-12-12 17:10:49 +00:00
|
|
|
var.dpl = 0x3;
|
2012-12-12 17:10:50 +00:00
|
|
|
if (seg == VCPU_SREG_CS)
|
|
|
|
var.type = 0x3;
|
2008-08-17 13:38:32 +00:00
|
|
|
ar = vmx_segment_access_rights(&var);
|
|
|
|
|
|
|
|
if (var.base != (var.selector << 4))
|
|
|
|
return false;
|
2012-12-20 14:57:44 +00:00
|
|
|
if (var.limit != 0xffff)
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
2012-12-12 17:10:49 +00:00
|
|
|
if (ar != 0xf3)
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool code_segment_valid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment cs;
|
|
|
|
unsigned int cs_rpl;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
|
2015-03-29 13:33:04 +00:00
|
|
|
cs_rpl = cs.selector & SEGMENT_RPL_MASK;
|
2008-08-17 13:38:32 +00:00
|
|
|
|
2009-01-04 21:26:52 +00:00
|
|
|
if (cs.unusable)
|
|
|
|
return false;
|
2015-08-13 20:18:48 +00:00
|
|
|
if (~cs.type & (VMX_AR_TYPE_CODE_MASK|VMX_AR_TYPE_ACCESSES_MASK))
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
|
|
|
if (!cs.s)
|
|
|
|
return false;
|
2015-08-13 20:18:48 +00:00
|
|
|
if (cs.type & VMX_AR_TYPE_WRITEABLE_MASK) {
|
2008-08-17 13:38:32 +00:00
|
|
|
if (cs.dpl > cs_rpl)
|
|
|
|
return false;
|
2009-01-04 21:26:52 +00:00
|
|
|
} else {
|
2008-08-17 13:38:32 +00:00
|
|
|
if (cs.dpl != cs_rpl)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!cs.present)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* TODO: Add Reserved field check, this'll require a new member in the kvm_segment_field structure */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool stack_segment_valid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment ss;
|
|
|
|
unsigned int ss_rpl;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
|
2015-03-29 13:33:04 +00:00
|
|
|
ss_rpl = ss.selector & SEGMENT_RPL_MASK;
|
2008-08-17 13:38:32 +00:00
|
|
|
|
2009-01-04 21:26:52 +00:00
|
|
|
if (ss.unusable)
|
|
|
|
return true;
|
|
|
|
if (ss.type != 3 && ss.type != 7)
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
|
|
|
if (!ss.s)
|
|
|
|
return false;
|
|
|
|
if (ss.dpl != ss_rpl) /* DPL != RPL */
|
|
|
|
return false;
|
|
|
|
if (!ss.present)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool data_segment_valid(struct kvm_vcpu *vcpu, int seg)
|
|
|
|
{
|
|
|
|
struct kvm_segment var;
|
|
|
|
unsigned int rpl;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &var, seg);
|
2015-03-29 13:33:04 +00:00
|
|
|
rpl = var.selector & SEGMENT_RPL_MASK;
|
2008-08-17 13:38:32 +00:00
|
|
|
|
2009-01-04 21:26:52 +00:00
|
|
|
if (var.unusable)
|
|
|
|
return true;
|
2008-08-17 13:38:32 +00:00
|
|
|
if (!var.s)
|
|
|
|
return false;
|
|
|
|
if (!var.present)
|
|
|
|
return false;
|
2015-08-13 20:18:48 +00:00
|
|
|
if (~var.type & (VMX_AR_TYPE_CODE_MASK|VMX_AR_TYPE_WRITEABLE_MASK)) {
|
2008-08-17 13:38:32 +00:00
|
|
|
if (var.dpl < rpl) /* DPL < RPL */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: Add other members to kvm_segment_field to allow checking for other access
|
|
|
|
* rights flags
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool tr_valid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment tr;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &tr, VCPU_SREG_TR);
|
|
|
|
|
2009-01-04 21:26:52 +00:00
|
|
|
if (tr.unusable)
|
|
|
|
return false;
|
2015-03-29 13:33:04 +00:00
|
|
|
if (tr.selector & SEGMENT_TI_MASK) /* TI = 1 */
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
2009-01-04 21:26:52 +00:00
|
|
|
if (tr.type != 3 && tr.type != 11) /* TODO: Check if guest is in IA32e mode */
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
|
|
|
if (!tr.present)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool ldtr_valid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment ldtr;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR);
|
|
|
|
|
2009-01-04 21:26:52 +00:00
|
|
|
if (ldtr.unusable)
|
|
|
|
return true;
|
2015-03-29 13:33:04 +00:00
|
|
|
if (ldtr.selector & SEGMENT_TI_MASK) /* TI = 1 */
|
2008-08-17 13:38:32 +00:00
|
|
|
return false;
|
|
|
|
if (ldtr.type != 2)
|
|
|
|
return false;
|
|
|
|
if (!ldtr.present)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment cs, ss;
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
|
|
|
|
vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
|
|
|
|
|
2015-03-29 13:33:04 +00:00
|
|
|
return ((cs.selector & SEGMENT_RPL_MASK) ==
|
|
|
|
(ss.selector & SEGMENT_RPL_MASK));
|
2008-08-17 13:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if guest state is valid. Returns true if valid, false if
|
|
|
|
* not.
|
|
|
|
* We assume that registers are always usable
|
|
|
|
*/
|
|
|
|
static bool guest_state_valid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2013-01-21 13:36:43 +00:00
|
|
|
if (enable_unrestricted_guest)
|
|
|
|
return true;
|
|
|
|
|
2008-08-17 13:38:32 +00:00
|
|
|
/* real mode guest state checks */
|
2013-04-14 13:07:37 +00:00
|
|
|
if (!is_protmode(vcpu) || (vmx_get_rflags(vcpu) & X86_EFLAGS_VM)) {
|
2008-08-17 13:38:32 +00:00
|
|
|
if (!rmode_segment_valid(vcpu, VCPU_SREG_CS))
|
|
|
|
return false;
|
|
|
|
if (!rmode_segment_valid(vcpu, VCPU_SREG_SS))
|
|
|
|
return false;
|
|
|
|
if (!rmode_segment_valid(vcpu, VCPU_SREG_DS))
|
|
|
|
return false;
|
|
|
|
if (!rmode_segment_valid(vcpu, VCPU_SREG_ES))
|
|
|
|
return false;
|
|
|
|
if (!rmode_segment_valid(vcpu, VCPU_SREG_FS))
|
|
|
|
return false;
|
|
|
|
if (!rmode_segment_valid(vcpu, VCPU_SREG_GS))
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
/* protected mode guest state checks */
|
|
|
|
if (!cs_ss_rpl_check(vcpu))
|
|
|
|
return false;
|
|
|
|
if (!code_segment_valid(vcpu))
|
|
|
|
return false;
|
|
|
|
if (!stack_segment_valid(vcpu))
|
|
|
|
return false;
|
|
|
|
if (!data_segment_valid(vcpu, VCPU_SREG_DS))
|
|
|
|
return false;
|
|
|
|
if (!data_segment_valid(vcpu, VCPU_SREG_ES))
|
|
|
|
return false;
|
|
|
|
if (!data_segment_valid(vcpu, VCPU_SREG_FS))
|
|
|
|
return false;
|
|
|
|
if (!data_segment_valid(vcpu, VCPU_SREG_GS))
|
|
|
|
return false;
|
|
|
|
if (!tr_valid(vcpu))
|
|
|
|
return false;
|
|
|
|
if (!ldtr_valid(vcpu))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
/* TODO:
|
|
|
|
* - Add checks on RIP
|
|
|
|
* - Add checks on RFLAGS
|
|
|
|
*/
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-10-08 13:02:08 +00:00
|
|
|
static int init_rmode_tss(struct kvm *kvm)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2011-03-09 07:41:04 +00:00
|
|
|
gfn_t fn;
|
2007-10-01 20:14:18 +00:00
|
|
|
u16 data = 0;
|
2014-09-16 11:37:40 +00:00
|
|
|
int idx, r;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2011-03-09 07:41:04 +00:00
|
|
|
idx = srcu_read_lock(&kvm->srcu);
|
2013-03-15 07:38:56 +00:00
|
|
|
fn = kvm->arch.tss_addr >> PAGE_SHIFT;
|
2007-10-01 20:14:18 +00:00
|
|
|
r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE);
|
|
|
|
if (r < 0)
|
2007-12-21 00:18:22 +00:00
|
|
|
goto out;
|
2007-10-01 20:14:18 +00:00
|
|
|
data = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE;
|
2008-08-13 06:10:33 +00:00
|
|
|
r = kvm_write_guest_page(kvm, fn++, &data,
|
|
|
|
TSS_IOPB_BASE_OFFSET, sizeof(u16));
|
2007-10-01 20:14:18 +00:00
|
|
|
if (r < 0)
|
2007-12-21 00:18:22 +00:00
|
|
|
goto out;
|
2007-10-01 20:14:18 +00:00
|
|
|
r = kvm_clear_guest_page(kvm, fn++, 0, PAGE_SIZE);
|
|
|
|
if (r < 0)
|
2007-12-21 00:18:22 +00:00
|
|
|
goto out;
|
2007-10-01 20:14:18 +00:00
|
|
|
r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE);
|
|
|
|
if (r < 0)
|
2007-12-21 00:18:22 +00:00
|
|
|
goto out;
|
2007-10-01 20:14:18 +00:00
|
|
|
data = ~0;
|
2007-12-21 00:18:22 +00:00
|
|
|
r = kvm_write_guest_page(kvm, fn, &data,
|
|
|
|
RMODE_TSS_SIZE - 2 * PAGE_SIZE - 1,
|
|
|
|
sizeof(u8));
|
|
|
|
out:
|
2011-03-09 07:41:04 +00:00
|
|
|
srcu_read_unlock(&kvm->srcu, idx);
|
2014-09-16 11:37:40 +00:00
|
|
|
return r;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 13:44:52 +00:00
|
|
|
static int init_rmode_identity_map(struct kvm *kvm)
|
|
|
|
{
|
2014-09-16 10:41:59 +00:00
|
|
|
int i, idx, r = 0;
|
2008-04-25 13:44:52 +00:00
|
|
|
pfn_t identity_map_pfn;
|
|
|
|
u32 tmp;
|
|
|
|
|
2009-03-23 16:26:32 +00:00
|
|
|
if (!enable_ept)
|
2014-09-16 10:41:59 +00:00
|
|
|
return 0;
|
2014-09-16 10:41:58 +00:00
|
|
|
|
|
|
|
/* Protect kvm->arch.ept_identity_pagetable_done. */
|
|
|
|
mutex_lock(&kvm->slots_lock);
|
|
|
|
|
2014-09-16 10:41:59 +00:00
|
|
|
if (likely(kvm->arch.ept_identity_pagetable_done))
|
2014-09-16 10:41:58 +00:00
|
|
|
goto out2;
|
|
|
|
|
2009-07-21 02:42:48 +00:00
|
|
|
identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT;
|
2014-09-16 10:41:58 +00:00
|
|
|
|
|
|
|
r = alloc_identity_pagetable(kvm);
|
2014-09-16 10:41:59 +00:00
|
|
|
if (r < 0)
|
2014-09-16 10:41:58 +00:00
|
|
|
goto out2;
|
|
|
|
|
2011-03-09 07:41:04 +00:00
|
|
|
idx = srcu_read_lock(&kvm->srcu);
|
2008-04-25 13:44:52 +00:00
|
|
|
r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
|
|
|
|
if (r < 0)
|
|
|
|
goto out;
|
|
|
|
/* Set up identity-mapping pagetable for EPT in real mode */
|
|
|
|
for (i = 0; i < PT32_ENT_PER_PAGE; i++) {
|
|
|
|
tmp = (i << 22) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
|
|
|
|
_PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
|
|
|
|
r = kvm_write_guest_page(kvm, identity_map_pfn,
|
|
|
|
&tmp, i * sizeof(tmp), sizeof(tmp));
|
|
|
|
if (r < 0)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
kvm->arch.ept_identity_pagetable_done = true;
|
2014-09-16 10:41:59 +00:00
|
|
|
|
2008-04-25 13:44:52 +00:00
|
|
|
out:
|
2011-03-09 07:41:04 +00:00
|
|
|
srcu_read_unlock(&kvm->srcu, idx);
|
2014-09-16 10:41:58 +00:00
|
|
|
|
|
|
|
out2:
|
|
|
|
mutex_unlock(&kvm->slots_lock);
|
2014-09-16 10:41:59 +00:00
|
|
|
return r;
|
2008-04-25 13:44:52 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void seg_setup(int seg)
|
|
|
|
{
|
2012-08-29 23:30:19 +00:00
|
|
|
const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
|
2009-06-08 18:34:16 +00:00
|
|
|
unsigned int ar;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
vmcs_write16(sf->selector, 0);
|
|
|
|
vmcs_writel(sf->base, 0);
|
|
|
|
vmcs_write32(sf->limit, 0xffff);
|
2012-12-20 14:57:46 +00:00
|
|
|
ar = 0x93;
|
|
|
|
if (seg == VCPU_SREG_CS)
|
|
|
|
ar |= 0x08; /* code segment */
|
2009-06-08 18:34:16 +00:00
|
|
|
|
|
|
|
vmcs_write32(sf->ar_bytes, ar);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2007-10-29 01:40:42 +00:00
|
|
|
static int alloc_apic_access_page(struct kvm *kvm)
|
|
|
|
{
|
KVM: fix error paths for failed gfn_to_page() calls
This bug was triggered:
[ 4220.198458] BUG: unable to handle kernel paging request at fffffffffffffffe
[ 4220.203907] IP: [<ffffffff81104d85>] put_page+0xf/0x34
......
[ 4220.237326] Call Trace:
[ 4220.237361] [<ffffffffa03830d0>] kvm_arch_destroy_vm+0xf9/0x101 [kvm]
[ 4220.237382] [<ffffffffa036fe53>] kvm_put_kvm+0xcc/0x127 [kvm]
[ 4220.237401] [<ffffffffa03702bc>] kvm_vcpu_release+0x18/0x1c [kvm]
[ 4220.237407] [<ffffffff81145425>] __fput+0x111/0x1ed
[ 4220.237411] [<ffffffff8114550f>] ____fput+0xe/0x10
[ 4220.237418] [<ffffffff81063511>] task_work_run+0x5d/0x88
[ 4220.237424] [<ffffffff8104c3f7>] do_exit+0x2bf/0x7ca
The test case:
printf(fmt, ##args); \
exit(-1);} while (0)
static int create_vm(void)
{
int sys_fd, vm_fd;
sys_fd = open("/dev/kvm", O_RDWR);
if (sys_fd < 0)
die("open /dev/kvm fail.\n");
vm_fd = ioctl(sys_fd, KVM_CREATE_VM, 0);
if (vm_fd < 0)
die("KVM_CREATE_VM fail.\n");
return vm_fd;
}
static int create_vcpu(int vm_fd)
{
int vcpu_fd;
vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
if (vcpu_fd < 0)
die("KVM_CREATE_VCPU ioctl.\n");
printf("Create vcpu.\n");
return vcpu_fd;
}
static void *vcpu_thread(void *arg)
{
int vm_fd = (int)(long)arg;
create_vcpu(vm_fd);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread;
int vm_fd;
(void)argc;
(void)argv;
vm_fd = create_vm();
pthread_create(&thread, NULL, vcpu_thread, (void *)(long)vm_fd);
printf("Exit.\n");
return 0;
}
It caused by release kvm->arch.ept_identity_map_addr which is the
error page.
The parent thread can send KILL signal to the vcpu thread when it was
exiting which stops faulting pages and potentially allocating memory.
So gfn_to_pfn/gfn_to_page may fail at this time
Fixed by checking the page before it is used
Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2012-09-07 06:14:20 +00:00
|
|
|
struct page *page;
|
2007-10-29 01:40:42 +00:00
|
|
|
struct kvm_userspace_memory_region kvm_userspace_mem;
|
|
|
|
int r = 0;
|
|
|
|
|
2009-12-23 16:35:26 +00:00
|
|
|
mutex_lock(&kvm->slots_lock);
|
2014-09-24 07:57:58 +00:00
|
|
|
if (kvm->arch.apic_access_page_done)
|
2007-10-29 01:40:42 +00:00
|
|
|
goto out;
|
|
|
|
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
|
|
|
|
kvm_userspace_mem.flags = 0;
|
2014-09-11 05:38:00 +00:00
|
|
|
kvm_userspace_mem.guest_phys_addr = APIC_DEFAULT_PHYS_BASE;
|
2007-10-29 01:40:42 +00:00
|
|
|
kvm_userspace_mem.memory_size = PAGE_SIZE;
|
2015-05-18 11:33:16 +00:00
|
|
|
r = __x86_set_memory_region(kvm, &kvm_userspace_mem);
|
2007-10-29 01:40:42 +00:00
|
|
|
if (r)
|
|
|
|
goto out;
|
2008-02-10 16:04:15 +00:00
|
|
|
|
2014-09-11 05:38:00 +00:00
|
|
|
page = gfn_to_page(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
|
KVM: fix error paths for failed gfn_to_page() calls
This bug was triggered:
[ 4220.198458] BUG: unable to handle kernel paging request at fffffffffffffffe
[ 4220.203907] IP: [<ffffffff81104d85>] put_page+0xf/0x34
......
[ 4220.237326] Call Trace:
[ 4220.237361] [<ffffffffa03830d0>] kvm_arch_destroy_vm+0xf9/0x101 [kvm]
[ 4220.237382] [<ffffffffa036fe53>] kvm_put_kvm+0xcc/0x127 [kvm]
[ 4220.237401] [<ffffffffa03702bc>] kvm_vcpu_release+0x18/0x1c [kvm]
[ 4220.237407] [<ffffffff81145425>] __fput+0x111/0x1ed
[ 4220.237411] [<ffffffff8114550f>] ____fput+0xe/0x10
[ 4220.237418] [<ffffffff81063511>] task_work_run+0x5d/0x88
[ 4220.237424] [<ffffffff8104c3f7>] do_exit+0x2bf/0x7ca
The test case:
printf(fmt, ##args); \
exit(-1);} while (0)
static int create_vm(void)
{
int sys_fd, vm_fd;
sys_fd = open("/dev/kvm", O_RDWR);
if (sys_fd < 0)
die("open /dev/kvm fail.\n");
vm_fd = ioctl(sys_fd, KVM_CREATE_VM, 0);
if (vm_fd < 0)
die("KVM_CREATE_VM fail.\n");
return vm_fd;
}
static int create_vcpu(int vm_fd)
{
int vcpu_fd;
vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
if (vcpu_fd < 0)
die("KVM_CREATE_VCPU ioctl.\n");
printf("Create vcpu.\n");
return vcpu_fd;
}
static void *vcpu_thread(void *arg)
{
int vm_fd = (int)(long)arg;
create_vcpu(vm_fd);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread;
int vm_fd;
(void)argc;
(void)argv;
vm_fd = create_vm();
pthread_create(&thread, NULL, vcpu_thread, (void *)(long)vm_fd);
printf("Exit.\n");
return 0;
}
It caused by release kvm->arch.ept_identity_map_addr which is the
error page.
The parent thread can send KILL signal to the vcpu thread when it was
exiting which stops faulting pages and potentially allocating memory.
So gfn_to_pfn/gfn_to_page may fail at this time
Fixed by checking the page before it is used
Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2012-09-07 06:14:20 +00:00
|
|
|
if (is_error_page(page)) {
|
|
|
|
r = -EFAULT;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2014-09-24 07:57:58 +00:00
|
|
|
/*
|
|
|
|
* Do not pin the page in memory, so that memory hot-unplug
|
|
|
|
* is able to migrate it.
|
|
|
|
*/
|
|
|
|
put_page(page);
|
|
|
|
kvm->arch.apic_access_page_done = true;
|
2007-10-29 01:40:42 +00:00
|
|
|
out:
|
2009-12-23 16:35:26 +00:00
|
|
|
mutex_unlock(&kvm->slots_lock);
|
2007-10-29 01:40:42 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2008-04-25 13:44:52 +00:00
|
|
|
static int alloc_identity_pagetable(struct kvm *kvm)
|
|
|
|
{
|
2014-09-16 10:41:58 +00:00
|
|
|
/* Called with kvm->slots_lock held. */
|
|
|
|
|
2008-04-25 13:44:52 +00:00
|
|
|
struct kvm_userspace_memory_region kvm_userspace_mem;
|
|
|
|
int r = 0;
|
|
|
|
|
2014-09-16 10:41:58 +00:00
|
|
|
BUG_ON(kvm->arch.ept_identity_pagetable_done);
|
|
|
|
|
2008-04-25 13:44:52 +00:00
|
|
|
kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
|
|
|
|
kvm_userspace_mem.flags = 0;
|
2009-07-21 02:42:48 +00:00
|
|
|
kvm_userspace_mem.guest_phys_addr =
|
|
|
|
kvm->arch.ept_identity_map_addr;
|
2008-04-25 13:44:52 +00:00
|
|
|
kvm_userspace_mem.memory_size = PAGE_SIZE;
|
2015-05-18 11:33:16 +00:00
|
|
|
r = __x86_set_memory_region(kvm, &kvm_userspace_mem);
|
2008-04-25 13:44:52 +00:00
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
static void allocate_vpid(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
int vpid;
|
|
|
|
|
|
|
|
vmx->vpid = 0;
|
2009-03-23 16:01:29 +00:00
|
|
|
if (!enable_vpid)
|
2008-01-17 07:14:33 +00:00
|
|
|
return;
|
|
|
|
spin_lock(&vmx_vpid_lock);
|
|
|
|
vpid = find_first_zero_bit(vmx_vpid_bitmap, VMX_NR_VPIDS);
|
|
|
|
if (vpid < VMX_NR_VPIDS) {
|
|
|
|
vmx->vpid = vpid;
|
|
|
|
__set_bit(vpid, vmx_vpid_bitmap);
|
|
|
|
}
|
|
|
|
spin_unlock(&vmx_vpid_lock);
|
|
|
|
}
|
|
|
|
|
2010-04-17 08:41:47 +00:00
|
|
|
static void free_vpid(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
if (!enable_vpid)
|
|
|
|
return;
|
|
|
|
spin_lock(&vmx_vpid_lock);
|
|
|
|
if (vmx->vpid != 0)
|
|
|
|
__clear_bit(vmx->vpid, vmx_vpid_bitmap);
|
|
|
|
spin_unlock(&vmx_vpid_lock);
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:50 +00:00
|
|
|
#define MSR_TYPE_R 1
|
|
|
|
#define MSR_TYPE_W 2
|
|
|
|
static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
|
|
|
|
u32 msr, int type)
|
2008-03-28 05:18:56 +00:00
|
|
|
{
|
2009-02-24 19:46:19 +00:00
|
|
|
int f = sizeof(unsigned long);
|
2008-03-28 05:18:56 +00:00
|
|
|
|
|
|
|
if (!cpu_has_vmx_msr_bitmap())
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
|
|
|
|
* have the write-low and read-high bitmap offsets the wrong way round.
|
|
|
|
* We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
|
|
|
|
*/
|
|
|
|
if (msr <= 0x1fff) {
|
2013-01-25 02:18:50 +00:00
|
|
|
if (type & MSR_TYPE_R)
|
|
|
|
/* read-low */
|
|
|
|
__clear_bit(msr, msr_bitmap + 0x000 / f);
|
|
|
|
|
|
|
|
if (type & MSR_TYPE_W)
|
|
|
|
/* write-low */
|
|
|
|
__clear_bit(msr, msr_bitmap + 0x800 / f);
|
|
|
|
|
2008-03-28 05:18:56 +00:00
|
|
|
} else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
|
|
|
|
msr &= 0x1fff;
|
2013-01-25 02:18:50 +00:00
|
|
|
if (type & MSR_TYPE_R)
|
|
|
|
/* read-high */
|
|
|
|
__clear_bit(msr, msr_bitmap + 0x400 / f);
|
|
|
|
|
|
|
|
if (type & MSR_TYPE_W)
|
|
|
|
/* write-high */
|
|
|
|
__clear_bit(msr, msr_bitmap + 0xc00 / f);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
|
|
|
|
u32 msr, int type)
|
|
|
|
{
|
|
|
|
int f = sizeof(unsigned long);
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_msr_bitmap())
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
|
|
|
|
* have the write-low and read-high bitmap offsets the wrong way round.
|
|
|
|
* We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
|
|
|
|
*/
|
|
|
|
if (msr <= 0x1fff) {
|
|
|
|
if (type & MSR_TYPE_R)
|
|
|
|
/* read-low */
|
|
|
|
__set_bit(msr, msr_bitmap + 0x000 / f);
|
|
|
|
|
|
|
|
if (type & MSR_TYPE_W)
|
|
|
|
/* write-low */
|
|
|
|
__set_bit(msr, msr_bitmap + 0x800 / f);
|
|
|
|
|
|
|
|
} else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
|
|
|
|
msr &= 0x1fff;
|
|
|
|
if (type & MSR_TYPE_R)
|
|
|
|
/* read-high */
|
|
|
|
__set_bit(msr, msr_bitmap + 0x400 / f);
|
|
|
|
|
|
|
|
if (type & MSR_TYPE_W)
|
|
|
|
/* write-high */
|
|
|
|
__set_bit(msr, msr_bitmap + 0xc00 / f);
|
|
|
|
|
2008-03-28 05:18:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:56:03 +00:00
|
|
|
/*
|
|
|
|
* If a msr is allowed by L0, we should check whether it is allowed by L1.
|
|
|
|
* The corresponding bit will be cleared unless both of L0 and L1 allow it.
|
|
|
|
*/
|
|
|
|
static void nested_vmx_disable_intercept_for_msr(unsigned long *msr_bitmap_l1,
|
|
|
|
unsigned long *msr_bitmap_nested,
|
|
|
|
u32 msr, int type)
|
|
|
|
{
|
|
|
|
int f = sizeof(unsigned long);
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_msr_bitmap()) {
|
|
|
|
WARN_ON(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
|
|
|
|
* have the write-low and read-high bitmap offsets the wrong way round.
|
|
|
|
* We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
|
|
|
|
*/
|
|
|
|
if (msr <= 0x1fff) {
|
|
|
|
if (type & MSR_TYPE_R &&
|
|
|
|
!test_bit(msr, msr_bitmap_l1 + 0x000 / f))
|
|
|
|
/* read-low */
|
|
|
|
__clear_bit(msr, msr_bitmap_nested + 0x000 / f);
|
|
|
|
|
|
|
|
if (type & MSR_TYPE_W &&
|
|
|
|
!test_bit(msr, msr_bitmap_l1 + 0x800 / f))
|
|
|
|
/* write-low */
|
|
|
|
__clear_bit(msr, msr_bitmap_nested + 0x800 / f);
|
|
|
|
|
|
|
|
} else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
|
|
|
|
msr &= 0x1fff;
|
|
|
|
if (type & MSR_TYPE_R &&
|
|
|
|
!test_bit(msr, msr_bitmap_l1 + 0x400 / f))
|
|
|
|
/* read-high */
|
|
|
|
__clear_bit(msr, msr_bitmap_nested + 0x400 / f);
|
|
|
|
|
|
|
|
if (type & MSR_TYPE_W &&
|
|
|
|
!test_bit(msr, msr_bitmap_l1 + 0xc00 / f))
|
|
|
|
/* write-high */
|
|
|
|
__clear_bit(msr, msr_bitmap_nested + 0xc00 / f);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-24 20:26:47 +00:00
|
|
|
static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only)
|
|
|
|
{
|
|
|
|
if (!longmode_only)
|
2013-01-25 02:18:50 +00:00
|
|
|
__vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy,
|
|
|
|
msr, MSR_TYPE_R | MSR_TYPE_W);
|
|
|
|
__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode,
|
|
|
|
msr, MSR_TYPE_R | MSR_TYPE_W);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_enable_intercept_msr_read_x2apic(u32 msr)
|
|
|
|
{
|
|
|
|
__vmx_enable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
|
|
|
|
msr, MSR_TYPE_R);
|
|
|
|
__vmx_enable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
|
|
|
|
msr, MSR_TYPE_R);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_disable_intercept_msr_read_x2apic(u32 msr)
|
|
|
|
{
|
|
|
|
__vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
|
|
|
|
msr, MSR_TYPE_R);
|
|
|
|
__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
|
|
|
|
msr, MSR_TYPE_R);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_disable_intercept_msr_write_x2apic(u32 msr)
|
|
|
|
{
|
|
|
|
__vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
|
|
|
|
msr, MSR_TYPE_W);
|
|
|
|
__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
|
|
|
|
msr, MSR_TYPE_W);
|
2009-02-24 20:26:47 +00:00
|
|
|
}
|
|
|
|
|
2015-07-29 09:49:59 +00:00
|
|
|
static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2015-07-29 10:05:37 +00:00
|
|
|
return enable_apicv && lapic_in_kernel(vcpu);
|
2015-07-29 09:49:59 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int max_irr;
|
|
|
|
void *vapic_page;
|
|
|
|
u16 status;
|
|
|
|
|
|
|
|
if (vmx->nested.pi_desc &&
|
|
|
|
vmx->nested.pi_pending) {
|
|
|
|
vmx->nested.pi_pending = false;
|
|
|
|
if (!pi_test_and_clear_on(vmx->nested.pi_desc))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
max_irr = find_last_bit(
|
|
|
|
(unsigned long *)vmx->nested.pi_desc->pir, 256);
|
|
|
|
|
|
|
|
if (max_irr == 256)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
vapic_page = kmap(vmx->nested.virtual_apic_page);
|
|
|
|
if (!vapic_page) {
|
|
|
|
WARN_ON(1);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
__kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page);
|
|
|
|
kunmap(vmx->nested.virtual_apic_page);
|
|
|
|
|
|
|
|
status = vmcs_read16(GUEST_INTR_STATUS);
|
|
|
|
if ((u8)max_irr > ((u8)status & 0xff)) {
|
|
|
|
status &= ~0xff;
|
|
|
|
status |= (u8)max_irr;
|
|
|
|
vmcs_write16(GUEST_INTR_STATUS, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-02-16 14:36:33 +00:00
|
|
|
static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
if (vcpu->mode == IN_GUEST_MODE) {
|
|
|
|
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu),
|
|
|
|
POSTED_INTR_VECTOR);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
|
|
|
|
int vector)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
|
|
if (is_guest_mode(vcpu) &&
|
|
|
|
vector == vmx->nested.posted_intr_nv) {
|
|
|
|
/* the PIR and ON have been set by L1. */
|
2015-02-16 14:36:33 +00:00
|
|
|
kvm_vcpu_trigger_posted_interrupt(vcpu);
|
2015-02-03 15:58:17 +00:00
|
|
|
/*
|
|
|
|
* If a posted intr is not recognized by hardware,
|
|
|
|
* we will accomplish it in the next vmentry.
|
|
|
|
*/
|
|
|
|
vmx->nested.pi_pending = true;
|
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2013-04-11 11:25:15 +00:00
|
|
|
/*
|
|
|
|
* Send interrupt to vcpu via posted interrupt way.
|
|
|
|
* 1. If target vcpu is running(non-root mode), send posted interrupt
|
|
|
|
* notification to vcpu and hardware will sync PIR to vIRR atomically.
|
|
|
|
* 2. If target vcpu isn't running(root mode), kick it to pick up the
|
|
|
|
* interrupt from PIR in next vmentry.
|
|
|
|
*/
|
|
|
|
static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int r;
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
r = vmx_deliver_nested_posted_interrupt(vcpu, vector);
|
|
|
|
if (!r)
|
|
|
|
return;
|
|
|
|
|
2013-04-11 11:25:15 +00:00
|
|
|
if (pi_test_and_set_pir(vector, &vmx->pi_desc))
|
|
|
|
return;
|
|
|
|
|
|
|
|
r = pi_test_and_set_on(&vmx->pi_desc);
|
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
2015-02-16 14:36:33 +00:00
|
|
|
if (r || !kvm_vcpu_trigger_posted_interrupt(vcpu))
|
2013-04-11 11:25:15 +00:00
|
|
|
kvm_vcpu_kick(vcpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
|
|
if (!pi_test_and_clear_on(&vmx->pi_desc))
|
|
|
|
return;
|
|
|
|
|
|
|
|
kvm_apic_update_irr(vcpu, vmx->pi_desc.pir);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:09:01 +00:00
|
|
|
/*
|
|
|
|
* Set up the vmcs's constant host-state fields, i.e., host-state fields that
|
|
|
|
* will not change in the lifetime of the guest.
|
|
|
|
* Note that host-state that does change is set elsewhere. E.g., host-state
|
|
|
|
* that is set differently for each CPU is set in vmx_vcpu_load(), not here.
|
|
|
|
*/
|
2013-04-11 11:25:10 +00:00
|
|
|
static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
|
2011-05-25 20:09:01 +00:00
|
|
|
{
|
|
|
|
u32 low32, high32;
|
|
|
|
unsigned long tmpl;
|
|
|
|
struct desc_ptr dt;
|
2014-10-08 16:02:13 +00:00
|
|
|
unsigned long cr4;
|
2011-05-25 20:09:01 +00:00
|
|
|
|
2012-09-20 18:01:49 +00:00
|
|
|
vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */
|
2011-05-25 20:09:01 +00:00
|
|
|
vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
|
|
|
|
|
2014-10-08 16:02:13 +00:00
|
|
|
/* Save the most likely value for this task's CR4 in the VMCS. */
|
2014-10-24 22:58:08 +00:00
|
|
|
cr4 = cr4_read_shadow();
|
2014-10-08 16:02:13 +00:00
|
|
|
vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */
|
|
|
|
vmx->host_state.vmcs_host_cr4 = cr4;
|
|
|
|
|
2011-05-25 20:09:01 +00:00
|
|
|
vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
|
2012-05-13 16:53:24 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
/*
|
|
|
|
* Load null selectors, so we can avoid reloading them in
|
|
|
|
* __vmx_load_host_state(), in case userspace uses the null selectors
|
|
|
|
* too (the expected case).
|
|
|
|
*/
|
|
|
|
vmcs_write16(HOST_DS_SELECTOR, 0);
|
|
|
|
vmcs_write16(HOST_ES_SELECTOR, 0);
|
|
|
|
#else
|
2011-05-25 20:09:01 +00:00
|
|
|
vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
|
|
|
|
vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */
|
2012-05-13 16:53:24 +00:00
|
|
|
#endif
|
2011-05-25 20:09:01 +00:00
|
|
|
vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
|
|
|
|
vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */
|
|
|
|
|
|
|
|
native_store_idt(&dt);
|
|
|
|
vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */
|
2013-04-11 11:25:10 +00:00
|
|
|
vmx->host_idt_base = dt.address;
|
2011-05-25 20:09:01 +00:00
|
|
|
|
2012-09-16 12:10:57 +00:00
|
|
|
vmcs_writel(HOST_RIP, vmx_return); /* 22.2.5 */
|
2011-05-25 20:09:01 +00:00
|
|
|
|
|
|
|
rdmsr(MSR_IA32_SYSENTER_CS, low32, high32);
|
|
|
|
vmcs_write32(HOST_IA32_SYSENTER_CS, low32);
|
|
|
|
rdmsrl(MSR_IA32_SYSENTER_EIP, tmpl);
|
|
|
|
vmcs_writel(HOST_IA32_SYSENTER_EIP, tmpl); /* 22.2.3 */
|
|
|
|
|
|
|
|
if (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PAT) {
|
|
|
|
rdmsr(MSR_IA32_CR_PAT, low32, high32);
|
|
|
|
vmcs_write64(HOST_IA32_PAT, low32 | ((u64) high32 << 32));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:09:31 +00:00
|
|
|
static void set_cr4_guest_host_mask(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
vmx->vcpu.arch.cr4_guest_owned_bits = KVM_CR4_GUEST_OWNED_BITS;
|
|
|
|
if (enable_ept)
|
|
|
|
vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE;
|
2011-05-25 20:10:02 +00:00
|
|
|
if (is_guest_mode(&vmx->vcpu))
|
|
|
|
vmx->vcpu.arch.cr4_guest_owned_bits &=
|
|
|
|
~get_vmcs12(&vmx->vcpu)->cr4_guest_host_mask;
|
2011-05-25 20:09:31 +00:00
|
|
|
vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits);
|
|
|
|
}
|
|
|
|
|
2013-04-11 11:25:12 +00:00
|
|
|
static u32 vmx_pin_based_exec_ctrl(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
u32 pin_based_exec_ctrl = vmcs_config.pin_based_exec_ctrl;
|
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
if (!vmx_cpu_uses_apicv(&vmx->vcpu))
|
2013-04-11 11:25:12 +00:00
|
|
|
pin_based_exec_ctrl &= ~PIN_BASED_POSTED_INTR;
|
|
|
|
return pin_based_exec_ctrl;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:09:31 +00:00
|
|
|
static u32 vmx_exec_control(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
u32 exec_control = vmcs_config.cpu_based_exec_ctrl;
|
2014-02-21 09:36:37 +00:00
|
|
|
|
|
|
|
if (vmx->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)
|
|
|
|
exec_control &= ~CPU_BASED_MOV_DR_EXITING;
|
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
if (!cpu_need_tpr_shadow(&vmx->vcpu)) {
|
2011-05-25 20:09:31 +00:00
|
|
|
exec_control &= ~CPU_BASED_TPR_SHADOW;
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
exec_control |= CPU_BASED_CR8_STORE_EXITING |
|
|
|
|
CPU_BASED_CR8_LOAD_EXITING;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (!enable_ept)
|
|
|
|
exec_control |= CPU_BASED_CR3_STORE_EXITING |
|
|
|
|
CPU_BASED_CR3_LOAD_EXITING |
|
|
|
|
CPU_BASED_INVLPG_EXITING;
|
|
|
|
return exec_control;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
u32 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl;
|
2015-07-29 10:05:37 +00:00
|
|
|
if (!cpu_need_virtualize_apic_accesses(&vmx->vcpu))
|
2011-05-25 20:09:31 +00:00
|
|
|
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
|
|
if (vmx->vpid == 0)
|
|
|
|
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
|
|
|
|
if (!enable_ept) {
|
|
|
|
exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
|
|
|
|
enable_unrestricted_guest = 0;
|
2012-07-02 01:18:48 +00:00
|
|
|
/* Enable INVPCID for non-ept guests may cause performance regression. */
|
|
|
|
exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
|
2011-05-25 20:09:31 +00:00
|
|
|
}
|
|
|
|
if (!enable_unrestricted_guest)
|
|
|
|
exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
|
|
|
|
if (!ple_gap)
|
|
|
|
exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
|
2015-07-29 10:05:37 +00:00
|
|
|
if (!vmx_cpu_uses_apicv(&vmx->vcpu))
|
2013-01-25 02:18:51 +00:00
|
|
|
exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
|
2013-01-25 02:18:50 +00:00
|
|
|
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
2013-04-18 11:35:25 +00:00
|
|
|
/* SECONDARY_EXEC_SHADOW_VMCS is enabled when L1 executes VMPTRLD
|
|
|
|
(handle_vmptrld).
|
|
|
|
We can NOT enable shadow_vmcs here because we don't have yet
|
|
|
|
a current VMCS12
|
|
|
|
*/
|
|
|
|
exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS;
|
2015-01-28 02:54:28 +00:00
|
|
|
/* PML is enabled/disabled in creating/destorying vcpu */
|
|
|
|
exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
|
|
|
|
|
2011-05-25 20:09:31 +00:00
|
|
|
return exec_control;
|
|
|
|
}
|
|
|
|
|
2011-07-11 19:33:44 +00:00
|
|
|
static void ept_set_mmio_spte_mask(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* EPT Misconfigurations can be generated if the value of bits 2:0
|
|
|
|
* of an EPT paging-structure entry is 110b (write/execute).
|
2013-06-07 08:51:23 +00:00
|
|
|
* Also, magic bits (0x3ull << 62) is set to quickly identify mmio
|
2011-07-11 19:33:44 +00:00
|
|
|
* spte.
|
|
|
|
*/
|
2013-06-07 08:51:23 +00:00
|
|
|
kvm_mmu_set_mmio_spte_mask((0x3ull << 62) | 0x6ull);
|
2011-07-11 19:33:44 +00:00
|
|
|
}
|
|
|
|
|
2014-12-02 11:14:58 +00:00
|
|
|
#define VMX_XSS_EXIT_BITMAP 0
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* Sets up the vmcs for emulated real mode.
|
|
|
|
*/
|
2007-07-30 06:31:43 +00:00
|
|
|
static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2011-06-01 10:57:30 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
unsigned long a;
|
2011-06-01 10:57:30 +00:00
|
|
|
#endif
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* I/O */
|
2009-02-24 19:46:19 +00:00
|
|
|
vmcs_write64(IO_BITMAP_A, __pa(vmx_io_bitmap_a));
|
|
|
|
vmcs_write64(IO_BITMAP_B, __pa(vmx_io_bitmap_b));
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2013-04-18 11:35:55 +00:00
|
|
|
if (enable_shadow_vmcs) {
|
|
|
|
vmcs_write64(VMREAD_BITMAP, __pa(vmx_vmread_bitmap));
|
|
|
|
vmcs_write64(VMWRITE_BITMAP, __pa(vmx_vmwrite_bitmap));
|
|
|
|
}
|
2008-03-28 05:18:56 +00:00
|
|
|
if (cpu_has_vmx_msr_bitmap())
|
2009-02-24 20:26:47 +00:00
|
|
|
vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_legacy));
|
2008-03-28 05:18:56 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
|
|
|
|
|
|
|
|
/* Control */
|
2013-04-11 11:25:12 +00:00
|
|
|
vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_ctrl(vmx));
|
2007-09-12 10:03:11 +00:00
|
|
|
|
2011-05-25 20:09:31 +00:00
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx_exec_control(vmx));
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2007-11-21 06:33:25 +00:00
|
|
|
if (cpu_has_secondary_exec_ctrls()) {
|
2011-05-25 20:09:31 +00:00
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
|
|
|
|
vmx_secondary_exec_control(vmx));
|
2007-11-21 06:33:25 +00:00
|
|
|
}
|
2007-10-29 01:40:42 +00:00
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
if (vmx_cpu_uses_apicv(&vmx->vcpu)) {
|
2013-01-25 02:18:51 +00:00
|
|
|
vmcs_write64(EOI_EXIT_BITMAP0, 0);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP1, 0);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP2, 0);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP3, 0);
|
|
|
|
|
|
|
|
vmcs_write16(GUEST_INTR_STATUS, 0);
|
2013-04-11 11:25:12 +00:00
|
|
|
|
|
|
|
vmcs_write64(POSTED_INTR_NV, POSTED_INTR_VECTOR);
|
|
|
|
vmcs_write64(POSTED_INTR_DESC_ADDR, __pa((&vmx->pi_desc)));
|
2013-01-25 02:18:51 +00:00
|
|
|
}
|
|
|
|
|
2009-10-09 10:03:20 +00:00
|
|
|
if (ple_gap) {
|
|
|
|
vmcs_write32(PLE_GAP, ple_gap);
|
2014-08-21 16:08:07 +00:00
|
|
|
vmx->ple_window = ple_window;
|
|
|
|
vmx->ple_window_dirty = true;
|
2009-10-09 10:03:20 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 19:28:04 +00:00
|
|
|
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0);
|
|
|
|
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, 0);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */
|
|
|
|
|
2010-10-19 14:46:55 +00:00
|
|
|
vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */
|
|
|
|
vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */
|
2013-04-11 11:25:10 +00:00
|
|
|
vmx_set_constant_host_state(vmx);
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
rdmsrl(MSR_FS_BASE, a);
|
|
|
|
vmcs_writel(HOST_FS_BASE, a); /* 22.2.4 */
|
|
|
|
rdmsrl(MSR_GS_BASE, a);
|
|
|
|
vmcs_writel(HOST_GS_BASE, a); /* 22.2.4 */
|
|
|
|
#else
|
|
|
|
vmcs_writel(HOST_FS_BASE, 0); /* 22.2.4 */
|
|
|
|
vmcs_writel(HOST_GS_BASE, 0); /* 22.2.4 */
|
|
|
|
#endif
|
|
|
|
|
2007-05-21 04:28:09 +00:00
|
|
|
vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
|
|
|
|
vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
|
2010-04-28 13:40:38 +00:00
|
|
|
vmcs_write64(VM_EXIT_MSR_LOAD_ADDR, __pa(vmx->msr_autoload.host));
|
2007-05-21 04:28:09 +00:00
|
|
|
vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0);
|
2010-04-28 13:40:38 +00:00
|
|
|
vmcs_write64(VM_ENTRY_MSR_LOAD_ADDR, __pa(vmx->msr_autoload.guest));
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2015-04-27 13:11:25 +00:00
|
|
|
if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT)
|
|
|
|
vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat);
|
2008-10-09 08:01:55 +00:00
|
|
|
|
2014-07-24 12:21:57 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
u32 index = vmx_msr_index[i];
|
|
|
|
u32 data_low, data_high;
|
2007-07-27 12:13:10 +00:00
|
|
|
int j = vmx->nmsrs;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
if (rdmsr_safe(index, &data_low, &data_high) < 0)
|
|
|
|
continue;
|
2007-02-01 07:48:13 +00:00
|
|
|
if (wrmsr_safe(index, data_low, data_high) < 0)
|
|
|
|
continue;
|
2009-09-07 08:14:12 +00:00
|
|
|
vmx->guest_msrs[j].index = i;
|
|
|
|
vmx->guest_msrs[j].data = 0;
|
2009-12-02 10:28:47 +00:00
|
|
|
vmx->guest_msrs[j].mask = -1ull;
|
2007-07-27 12:13:10 +00:00
|
|
|
++vmx->nmsrs;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2013-11-25 13:37:13 +00:00
|
|
|
|
|
|
|
vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
/* 22.2.1, 20.8.1 */
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_init(vmx, vmcs_config.vmentry_ctrl);
|
2007-07-29 08:07:42 +00:00
|
|
|
|
2007-10-21 09:00:39 +00:00
|
|
|
vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
|
2011-05-25 20:09:31 +00:00
|
|
|
set_cr4_guest_host_mask(vmx);
|
2007-10-21 09:00:39 +00:00
|
|
|
|
2014-12-02 11:14:58 +00:00
|
|
|
if (vmx_xsaves_supported())
|
|
|
|
vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP);
|
|
|
|
|
2007-10-21 09:00:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
|
2007-10-21 09:00:39 +00:00
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2014-01-24 15:48:44 +00:00
|
|
|
struct msr_data apic_base_msr;
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
u64 cr0;
|
2007-10-21 09:00:39 +00:00
|
|
|
|
2009-06-09 11:10:45 +00:00
|
|
|
vmx->rmode.vm86_active = 0;
|
2007-10-21 09:00:39 +00:00
|
|
|
|
2008-09-26 07:30:57 +00:00
|
|
|
vmx->soft_vnmi_blocked = 0;
|
|
|
|
|
2007-12-13 15:50:52 +00:00
|
|
|
vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
kvm_set_cr8(vcpu, 0);
|
|
|
|
|
|
|
|
if (!init_event) {
|
|
|
|
apic_base_msr.data = APIC_DEFAULT_PHYS_BASE |
|
|
|
|
MSR_IA32_APICBASE_ENABLE;
|
|
|
|
if (kvm_vcpu_is_reset_bsp(vcpu))
|
|
|
|
apic_base_msr.data |= MSR_IA32_APICBASE_BSP;
|
|
|
|
apic_base_msr.host_initiated = true;
|
|
|
|
kvm_set_apic_base(vcpu, &apic_base_msr);
|
|
|
|
}
|
2007-10-21 09:00:39 +00:00
|
|
|
|
2011-04-27 16:42:18 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
|
|
|
|
2008-08-20 12:07:31 +00:00
|
|
|
seg_setup(VCPU_SREG_CS);
|
2013-03-13 11:42:34 +00:00
|
|
|
vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
|
2013-03-19 15:30:26 +00:00
|
|
|
vmcs_write32(GUEST_CS_BASE, 0xffff0000);
|
2007-10-21 09:00:39 +00:00
|
|
|
|
|
|
|
seg_setup(VCPU_SREG_DS);
|
|
|
|
seg_setup(VCPU_SREG_ES);
|
|
|
|
seg_setup(VCPU_SREG_FS);
|
|
|
|
seg_setup(VCPU_SREG_GS);
|
|
|
|
seg_setup(VCPU_SREG_SS);
|
|
|
|
|
|
|
|
vmcs_write16(GUEST_TR_SELECTOR, 0);
|
|
|
|
vmcs_writel(GUEST_TR_BASE, 0);
|
|
|
|
vmcs_write32(GUEST_TR_LIMIT, 0xffff);
|
|
|
|
vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
|
|
|
|
|
|
|
|
vmcs_write16(GUEST_LDTR_SELECTOR, 0);
|
|
|
|
vmcs_writel(GUEST_LDTR_BASE, 0);
|
|
|
|
vmcs_write32(GUEST_LDTR_LIMIT, 0xffff);
|
|
|
|
vmcs_write32(GUEST_LDTR_AR_BYTES, 0x00082);
|
|
|
|
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
if (!init_event) {
|
|
|
|
vmcs_write32(GUEST_SYSENTER_CS, 0);
|
|
|
|
vmcs_writel(GUEST_SYSENTER_ESP, 0);
|
|
|
|
vmcs_writel(GUEST_SYSENTER_EIP, 0);
|
|
|
|
vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
|
|
|
|
}
|
2007-10-21 09:00:39 +00:00
|
|
|
|
|
|
|
vmcs_writel(GUEST_RFLAGS, 0x02);
|
2013-03-13 11:42:34 +00:00
|
|
|
kvm_rip_write(vcpu, 0xfff0);
|
2007-10-21 09:00:39 +00:00
|
|
|
|
|
|
|
vmcs_writel(GUEST_GDTR_BASE, 0);
|
|
|
|
vmcs_write32(GUEST_GDTR_LIMIT, 0xffff);
|
|
|
|
|
|
|
|
vmcs_writel(GUEST_IDTR_BASE, 0);
|
|
|
|
vmcs_write32(GUEST_IDTR_LIMIT, 0xffff);
|
|
|
|
|
2010-12-06 16:53:38 +00:00
|
|
|
vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
|
2007-10-21 09:00:39 +00:00
|
|
|
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
|
|
|
|
vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
|
|
|
|
|
|
|
|
setup_msrs(vmx);
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */
|
|
|
|
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
if (cpu_has_vmx_tpr_shadow() && !init_event) {
|
2007-10-29 01:40:42 +00:00
|
|
|
vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0);
|
2015-07-29 10:05:37 +00:00
|
|
|
if (cpu_need_tpr_shadow(vcpu))
|
2007-10-29 01:40:42 +00:00
|
|
|
vmcs_write64(VIRTUAL_APIC_PAGE_ADDR,
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
__pa(vcpu->arch.apic->regs));
|
2007-10-29 01:40:42 +00:00
|
|
|
vmcs_write32(TPR_THRESHOLD, 0);
|
|
|
|
}
|
|
|
|
|
2014-11-02 06:54:30 +00:00
|
|
|
kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
if (vmx_cpu_uses_apicv(vcpu))
|
2013-04-11 11:25:12 +00:00
|
|
|
memset(&vmx->pi_desc, 0, sizeof(struct pi_desc));
|
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
if (vmx->vpid != 0)
|
|
|
|
vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
|
|
|
|
|
KVM: x86: INIT and reset sequences are different
x86 architecture defines differences between the reset and INIT sequences.
INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
References (from Intel SDM):
"If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
to a specific processor or system wide) do not cause the MP protocol to be
repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
[Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
"If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
changed." [9.2: X87 FPU INITIALIZATION]
"The state of the local APIC following an INIT reset is the same as it is after
a power-up or hardware reset, except that the APIC ID and arbitration ID
registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
("Wait-for-SIPI" State)]
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-04-13 11:34:08 +00:00
|
|
|
cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
|
|
|
|
vmx_set_cr0(vcpu, cr0); /* enter rmode */
|
|
|
|
vmx->vcpu.arch.cr0 = cr0;
|
|
|
|
vmx_set_cr4(vcpu, 0);
|
|
|
|
if (!init_event)
|
|
|
|
vmx_set_efer(vcpu, 0);
|
|
|
|
vmx_fpu_activate(vcpu);
|
|
|
|
update_exception_bitmap(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2010-06-07 02:32:29 +00:00
|
|
|
vpid_sync_context(vmx);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
KVM: nVMX: Correct handling of interrupt injection
The code in this patch correctly emulates external-interrupt injection
while a nested guest L2 is running.
Because of this code's relative un-obviousness, I include here a longer-than-
usual justification for what it does - much longer than the code itself ;-)
To understand how to correctly emulate interrupt injection while L2 is
running, let's look first at what we need to emulate: How would things look
like if the extra L0 hypervisor layer is removed, and instead of L0 injecting
an interrupt, we had hardware delivering an interrupt?
Now we have L1 running on bare metal with a guest L2, and the hardware
generates an interrupt. Assuming that L1 set PIN_BASED_EXT_INTR_MASK to 1, and
VM_EXIT_ACK_INTR_ON_EXIT to 0 (we'll revisit these assumptions below), what
happens now is this: The processor exits from L2 to L1, with an external-
interrupt exit reason but without an interrupt vector. L1 runs, with
interrupts disabled, and it doesn't yet know what the interrupt was. Soon
after, it enables interrupts and only at that moment, it gets the interrupt
from the processor. when L1 is KVM, Linux handles this interrupt.
Now we need exactly the same thing to happen when that L1->L2 system runs
on top of L0, instead of real hardware. This is how we do this:
When L0 wants to inject an interrupt, it needs to exit from L2 to L1, with
external-interrupt exit reason (with an invalid interrupt vector), and run L1.
Just like in the bare metal case, it likely can't deliver the interrupt to
L1 now because L1 is running with interrupts disabled, in which case it turns
on the interrupt window when running L1 after the exit. L1 will soon enable
interrupts, and at that point L0 will gain control again and inject the
interrupt to L1.
Finally, there is an extra complication in the code: when nested_run_pending,
we cannot return to L1 now, and must launch L2. We need to remember the
interrupt we wanted to inject (and not clear it now), and do it on the
next exit.
The above explanation shows that the relative strangeness of the nested
interrupt injection code in this patch, and the extra interrupt-window
exit incurred, are in fact necessary for accurate emulation, and are not
just an unoptimized implementation.
Let's revisit now the two assumptions made above:
If L1 turns off PIN_BASED_EXT_INTR_MASK (no hypervisor that I know
does, by the way), things are simple: L0 may inject the interrupt directly
to the L2 guest - using the normal code path that injects to any guest.
We support this case in the code below.
If L1 turns on VM_EXIT_ACK_INTR_ON_EXIT, things look very different from the
description above: L1 expects to see an exit from L2 with the interrupt vector
already filled in the exit information, and does not expect to be interrupted
again with this interrupt. The current code does not (yet) support this case,
so we do not allow the VM_EXIT_ACK_INTR_ON_EXIT exit-control to be turned on
by L1.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:13:06 +00:00
|
|
|
/*
|
|
|
|
* In nested virtualization, check if L1 asked to exit on external interrupts.
|
|
|
|
* For most existing hypervisors, this will always return true.
|
|
|
|
*/
|
|
|
|
static bool nested_exit_on_intr(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return get_vmcs12(vcpu)->pin_based_vm_exec_control &
|
|
|
|
PIN_BASED_EXT_INTR_MASK;
|
|
|
|
}
|
|
|
|
|
2014-04-19 22:17:45 +00:00
|
|
|
/*
|
|
|
|
* In nested virtualization, check if L1 has set
|
|
|
|
* VM_EXIT_ACK_INTR_ON_EXIT
|
|
|
|
*/
|
|
|
|
static bool nested_exit_intr_ack_set(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return get_vmcs12(vcpu)->vm_exit_controls &
|
|
|
|
VM_EXIT_ACK_INTR_ON_EXIT;
|
|
|
|
}
|
|
|
|
|
2013-04-14 19:04:26 +00:00
|
|
|
static bool nested_exit_on_nmi(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return get_vmcs12(vcpu)->pin_based_vm_exec_control &
|
|
|
|
PIN_BASED_NMI_EXITING;
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:15 +00:00
|
|
|
static void enable_irq_window(struct kvm_vcpu *vcpu)
|
2008-09-26 07:30:57 +00:00
|
|
|
{
|
|
|
|
u32 cpu_based_vm_exec_control;
|
2013-04-28 08:50:52 +00:00
|
|
|
|
2008-09-26 07:30:57 +00:00
|
|
|
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:15 +00:00
|
|
|
static void enable_nmi_window(struct kvm_vcpu *vcpu)
|
2008-09-26 07:30:57 +00:00
|
|
|
{
|
|
|
|
u32 cpu_based_vm_exec_control;
|
|
|
|
|
2014-03-07 19:03:15 +00:00
|
|
|
if (!cpu_has_virtual_nmis() ||
|
|
|
|
vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_STI) {
|
|
|
|
enable_irq_window(vcpu);
|
|
|
|
return;
|
|
|
|
}
|
2008-09-26 07:30:57 +00:00
|
|
|
|
|
|
|
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING;
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
|
|
|
|
}
|
|
|
|
|
2009-05-11 10:35:50 +00:00
|
|
|
static void vmx_inject_irq(struct kvm_vcpu *vcpu)
|
2007-07-06 09:20:49 +00:00
|
|
|
{
|
2007-11-22 09:42:59 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-05-11 10:35:50 +00:00
|
|
|
uint32_t intr;
|
|
|
|
int irq = vcpu->arch.interrupt.nr;
|
2007-11-22 09:42:59 +00:00
|
|
|
|
2009-06-17 12:22:14 +00:00
|
|
|
trace_kvm_inj_virq(irq);
|
2008-04-10 19:31:10 +00:00
|
|
|
|
2008-09-01 12:57:51 +00:00
|
|
|
++vcpu->stat.irq_injections;
|
2009-06-09 11:10:45 +00:00
|
|
|
if (vmx->rmode.vm86_active) {
|
2011-04-13 14:12:54 +00:00
|
|
|
int inc_eip = 0;
|
|
|
|
if (vcpu->arch.interrupt.soft)
|
|
|
|
inc_eip = vcpu->arch.event_exit_inst_len;
|
|
|
|
if (kvm_inject_realmode_interrupt(vcpu, irq, inc_eip) != EMULATE_DONE)
|
2010-09-19 12:34:07 +00:00
|
|
|
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
2007-07-06 09:20:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2009-05-11 10:35:50 +00:00
|
|
|
intr = irq | INTR_INFO_VALID_MASK;
|
|
|
|
if (vcpu->arch.interrupt.soft) {
|
|
|
|
intr |= INTR_TYPE_SOFT_INTR;
|
|
|
|
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
|
|
|
|
vmx->vcpu.arch.event_exit_inst_len);
|
|
|
|
} else
|
|
|
|
intr |= INTR_TYPE_EXT_INTR;
|
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr);
|
2007-07-06 09:20:49 +00:00
|
|
|
}
|
|
|
|
|
2008-05-15 10:23:25 +00:00
|
|
|
static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2008-09-26 07:30:51 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
2011-05-25 20:13:36 +00:00
|
|
|
if (is_guest_mode(vcpu))
|
|
|
|
return;
|
|
|
|
|
2008-09-26 07:30:57 +00:00
|
|
|
if (!cpu_has_virtual_nmis()) {
|
|
|
|
/*
|
|
|
|
* Tracking the NMI-blocked state in software is built upon
|
|
|
|
* finding the next open IRQ window. This, in turn, depends on
|
|
|
|
* well-behaving guests: They have to keep IRQs disabled at
|
|
|
|
* least as long as the NMI handler runs. Otherwise we may
|
|
|
|
* cause NMI nesting, maybe breaking the guest. But as this is
|
|
|
|
* highly unlikely, we can live with the residual risk.
|
|
|
|
*/
|
|
|
|
vmx->soft_vnmi_blocked = 1;
|
|
|
|
vmx->vnmi_blocked_time = 0;
|
|
|
|
}
|
|
|
|
|
2008-09-26 07:30:56 +00:00
|
|
|
++vcpu->stat.nmi_injections;
|
2011-03-07 14:52:07 +00:00
|
|
|
vmx->nmi_known_unmasked = false;
|
2009-06-09 11:10:45 +00:00
|
|
|
if (vmx->rmode.vm86_active) {
|
2011-04-13 14:12:54 +00:00
|
|
|
if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE)
|
2010-09-19 12:34:07 +00:00
|
|
|
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
2008-09-26 07:30:51 +00:00
|
|
|
return;
|
|
|
|
}
|
2008-05-15 10:23:25 +00:00
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
|
|
|
|
INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
|
|
|
|
}
|
|
|
|
|
2009-11-12 00:04:25 +00:00
|
|
|
static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
if (!cpu_has_virtual_nmis())
|
|
|
|
return to_vmx(vcpu)->soft_vnmi_blocked;
|
2011-03-07 14:52:07 +00:00
|
|
|
if (to_vmx(vcpu)->nmi_known_unmasked)
|
|
|
|
return false;
|
2010-05-04 09:24:12 +00:00
|
|
|
return vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_NMI;
|
2009-11-12 00:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
|
|
if (!cpu_has_virtual_nmis()) {
|
|
|
|
if (vmx->soft_vnmi_blocked != masked) {
|
|
|
|
vmx->soft_vnmi_blocked = masked;
|
|
|
|
vmx->vnmi_blocked_time = 0;
|
|
|
|
}
|
|
|
|
} else {
|
2011-03-07 14:52:07 +00:00
|
|
|
vmx->nmi_known_unmasked = !masked;
|
2009-11-12 00:04:25 +00:00
|
|
|
if (masked)
|
|
|
|
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
|
|
|
|
GUEST_INTR_STATE_NMI);
|
|
|
|
else
|
|
|
|
vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
|
|
|
|
GUEST_INTR_STATE_NMI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-14 10:12:47 +00:00
|
|
|
static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2014-03-07 19:03:12 +00:00
|
|
|
if (to_vmx(vcpu)->nested.nested_run_pending)
|
|
|
|
return 0;
|
2013-04-14 19:04:26 +00:00
|
|
|
|
2013-04-14 10:12:47 +00:00
|
|
|
if (!cpu_has_virtual_nmis() && to_vmx(vcpu)->soft_vnmi_blocked)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
|
|
|
|
(GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_STI
|
|
|
|
| GUEST_INTR_STATE_NMI));
|
|
|
|
}
|
|
|
|
|
2009-03-23 10:12:11 +00:00
|
|
|
static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2014-03-07 19:03:12 +00:00
|
|
|
return (!to_vmx(vcpu)->nested.nested_run_pending &&
|
|
|
|
vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
|
2009-04-21 14:45:07 +00:00
|
|
|
!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
|
|
|
|
(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
|
2009-03-23 10:12:11 +00:00
|
|
|
}
|
|
|
|
|
2007-10-24 22:29:55 +00:00
|
|
|
static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct kvm_userspace_memory_region tss_mem = {
|
2008-10-16 09:30:58 +00:00
|
|
|
.slot = TSS_PRIVATE_MEMSLOT,
|
2007-10-24 22:29:55 +00:00
|
|
|
.guest_phys_addr = addr,
|
|
|
|
.memory_size = PAGE_SIZE * 3,
|
|
|
|
.flags = 0,
|
|
|
|
};
|
|
|
|
|
2015-05-18 11:33:16 +00:00
|
|
|
ret = x86_set_memory_region(kvm, &tss_mem);
|
2007-10-24 22:29:55 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2007-12-14 02:20:16 +00:00
|
|
|
kvm->arch.tss_addr = addr;
|
2014-09-16 11:37:40 +00:00
|
|
|
return init_rmode_tss(kvm);
|
2007-10-24 22:29:55 +00:00
|
|
|
}
|
|
|
|
|
2012-12-20 14:57:47 +00:00
|
|
|
static bool rmode_exception(struct kvm_vcpu *vcpu, int vec)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2008-07-14 10:28:51 +00:00
|
|
|
switch (vec) {
|
|
|
|
case BP_VECTOR:
|
2010-02-23 16:47:53 +00:00
|
|
|
/*
|
|
|
|
* Update instruction length as we may reinject the exception
|
|
|
|
* from user space while in guest debugging mode.
|
|
|
|
*/
|
|
|
|
to_vmx(vcpu)->vcpu.arch.event_exit_inst_len =
|
|
|
|
vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
|
2008-12-15 12:52:10 +00:00
|
|
|
if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
|
2012-12-20 14:57:47 +00:00
|
|
|
return false;
|
|
|
|
/* fall through */
|
|
|
|
case DB_VECTOR:
|
|
|
|
if (vcpu->guest_debug &
|
|
|
|
(KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
|
|
|
|
return false;
|
2008-12-15 12:52:10 +00:00
|
|
|
/* fall through */
|
|
|
|
case DE_VECTOR:
|
2008-07-14 10:28:51 +00:00
|
|
|
case OF_VECTOR:
|
|
|
|
case BR_VECTOR:
|
|
|
|
case UD_VECTOR:
|
|
|
|
case DF_VECTOR:
|
|
|
|
case SS_VECTOR:
|
|
|
|
case GP_VECTOR:
|
|
|
|
case MF_VECTOR:
|
2012-12-20 14:57:47 +00:00
|
|
|
return true;
|
|
|
|
break;
|
2008-07-14 10:28:51 +00:00
|
|
|
}
|
2012-12-20 14:57:47 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int handle_rmode_exception(struct kvm_vcpu *vcpu,
|
|
|
|
int vec, u32 err_code)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Instruction with address size override prefix opcode 0x67
|
|
|
|
* Cause the #SS fault with 0 error code in VM86 mode.
|
|
|
|
*/
|
|
|
|
if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) {
|
|
|
|
if (emulate_instruction(vcpu, 0) == EMULATE_DONE) {
|
|
|
|
if (vcpu->arch.halt_request) {
|
|
|
|
vcpu->arch.halt_request = 0;
|
2015-03-02 19:43:31 +00:00
|
|
|
return kvm_vcpu_halt(vcpu);
|
2012-12-20 14:57:47 +00:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Forward all other exceptions that are valid in real mode.
|
|
|
|
* FIXME: Breaks guest debugging in real mode, needs to be fixed with
|
|
|
|
* the required debugging infrastructure rework.
|
|
|
|
*/
|
|
|
|
kvm_queue_exception(vcpu, vec);
|
|
|
|
return 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2009-06-08 09:37:09 +00:00
|
|
|
/*
|
|
|
|
* Trigger machine check on the host. We assume all the MSRs are already set up
|
|
|
|
* by the CPU and that we still run on the same CPU as the MCE occurred on.
|
|
|
|
* We pass a fake environment to the machine check handler because we want
|
|
|
|
* the guest to be always treated like user space, no matter what context
|
|
|
|
* it used internally.
|
|
|
|
*/
|
|
|
|
static void kvm_machine_check(void)
|
|
|
|
{
|
|
|
|
#if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_64)
|
|
|
|
struct pt_regs regs = {
|
|
|
|
.cs = 3, /* Fake ring 3 no matter what the guest ran on */
|
|
|
|
.flags = X86_EFLAGS_IF,
|
|
|
|
};
|
|
|
|
|
|
|
|
do_machine_check(®s, 0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_machine_check(struct kvm_vcpu *vcpu)
|
2009-06-08 09:37:09 +00:00
|
|
|
{
|
|
|
|
/* already handled by vcpu_run */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_exception(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-11-22 09:30:47 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-08-24 08:10:17 +00:00
|
|
|
struct kvm_run *kvm_run = vcpu->run;
|
2008-12-15 12:52:10 +00:00
|
|
|
u32 intr_info, ex_no, error_code;
|
2008-12-15 12:52:10 +00:00
|
|
|
unsigned long cr2, rip, dr6;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
u32 vect_info;
|
|
|
|
enum emulation_result er;
|
|
|
|
|
2007-11-22 09:30:47 +00:00
|
|
|
vect_info = vmx->idt_vectoring_info;
|
2011-03-07 15:39:45 +00:00
|
|
|
intr_info = vmx->exit_intr_info;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2009-06-08 09:37:09 +00:00
|
|
|
if (is_machine_check(intr_info))
|
2009-08-24 08:10:17 +00:00
|
|
|
return handle_machine_check(vcpu);
|
2009-06-08 09:37:09 +00:00
|
|
|
|
2008-09-26 07:30:46 +00:00
|
|
|
if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR)
|
2007-10-09 10:12:19 +00:00
|
|
|
return 1; /* already handled by vmx_vcpu_run() */
|
2007-04-27 06:29:49 +00:00
|
|
|
|
|
|
|
if (is_no_device(intr_info)) {
|
2007-05-02 17:40:00 +00:00
|
|
|
vmx_fpu_activate(vcpu);
|
2007-04-27 06:29:49 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-09-17 19:57:50 +00:00
|
|
|
if (is_invalid_opcode(intr_info)) {
|
2015-03-09 19:56:43 +00:00
|
|
|
if (is_guest_mode(vcpu)) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
2010-12-21 10:12:02 +00:00
|
|
|
er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD);
|
2007-09-17 19:57:50 +00:00
|
|
|
if (er != EMULATE_DONE)
|
2007-11-25 13:22:50 +00:00
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
2007-09-17 19:57:50 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
error_code = 0;
|
2008-02-11 16:26:38 +00:00
|
|
|
if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
|
2012-10-17 05:48:06 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The #PF with PFEC.RSVD = 1 indicates the guest is accessing
|
|
|
|
* MMIO, it is better to report an internal error.
|
|
|
|
* See the comments in vmx_handle_exit.
|
|
|
|
*/
|
|
|
|
if ((vect_info & VECTORING_INFO_VALID_MASK) &&
|
|
|
|
!(is_page_fault(intr_info) && !(error_code & PFERR_RSVD_MASK))) {
|
|
|
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
|
|
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_SIMUL_EX;
|
2015-04-02 19:11:05 +00:00
|
|
|
vcpu->run->internal.ndata = 3;
|
2012-10-17 05:48:06 +00:00
|
|
|
vcpu->run->internal.data[0] = vect_info;
|
|
|
|
vcpu->run->internal.data[1] = intr_info;
|
2015-04-02 19:11:05 +00:00
|
|
|
vcpu->run->internal.data[2] = error_code;
|
2012-10-17 05:48:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
if (is_page_fault(intr_info)) {
|
2008-04-28 04:24:45 +00:00
|
|
|
/* EPT won't cause page fault directly */
|
2011-08-02 10:34:57 +00:00
|
|
|
BUG_ON(enable_ept);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
cr2 = vmcs_readl(EXIT_QUALIFICATION);
|
2009-06-17 12:22:14 +00:00
|
|
|
trace_kvm_page_fault(cr2, error_code);
|
|
|
|
|
2009-05-11 10:35:46 +00:00
|
|
|
if (kvm_event_needs_reinjection(vcpu))
|
2008-07-19 05:57:05 +00:00
|
|
|
kvm_mmu_unprotect_page_virt(vcpu, cr2);
|
2010-12-21 10:12:07 +00:00
|
|
|
return kvm_mmu_page_fault(vcpu, cr2, error_code, NULL, 0);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2008-12-15 12:52:10 +00:00
|
|
|
ex_no = intr_info & INTR_INFO_VECTOR_MASK;
|
2012-12-20 14:57:47 +00:00
|
|
|
|
|
|
|
if (vmx->rmode.vm86_active && rmode_exception(vcpu, ex_no))
|
|
|
|
return handle_rmode_exception(vcpu, ex_no, error_code);
|
|
|
|
|
2008-12-15 12:52:10 +00:00
|
|
|
switch (ex_no) {
|
|
|
|
case DB_VECTOR:
|
|
|
|
dr6 = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
if (!(vcpu->guest_debug &
|
|
|
|
(KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
|
2014-01-04 17:47:17 +00:00
|
|
|
vcpu->arch.dr6 &= ~15;
|
2014-07-15 14:37:46 +00:00
|
|
|
vcpu->arch.dr6 |= dr6 | DR6_RTM;
|
2014-04-16 09:02:51 +00:00
|
|
|
if (!(dr6 & ~DR6_RESERVED)) /* icebp */
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
|
2008-12-15 12:52:10 +00:00
|
|
|
kvm_queue_exception(vcpu, DB_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1;
|
|
|
|
kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
|
|
|
|
/* fall through */
|
|
|
|
case BP_VECTOR:
|
2010-02-23 16:47:53 +00:00
|
|
|
/*
|
|
|
|
* Update instruction length as we may reinject #BP from
|
|
|
|
* user space while in guest debugging mode. Reading it for
|
|
|
|
* #DB as well causes no harm, it is not used in that case.
|
|
|
|
*/
|
|
|
|
vmx->vcpu.arch.event_exit_inst_len =
|
|
|
|
vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
kvm_run->exit_reason = KVM_EXIT_DEBUG;
|
2011-04-28 12:59:33 +00:00
|
|
|
rip = kvm_rip_read(vcpu);
|
2008-12-15 12:52:10 +00:00
|
|
|
kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
|
|
|
|
kvm_run->debug.arch.exception = ex_no;
|
2008-12-15 12:52:10 +00:00
|
|
|
break;
|
|
|
|
default:
|
2008-12-15 12:52:10 +00:00
|
|
|
kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
|
|
|
|
kvm_run->ex.exception = ex_no;
|
|
|
|
kvm_run->ex.error_code = error_code;
|
2008-12-15 12:52:10 +00:00
|
|
|
break;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_external_interrupt(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-04-19 14:27:43 +00:00
|
|
|
++vcpu->stat.irq_exits;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_triple_fault(struct kvm_vcpu *vcpu)
|
2007-02-12 08:54:36 +00:00
|
|
|
{
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
|
2007-02-12 08:54:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_io(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-09-12 06:18:28 +00:00
|
|
|
unsigned long exit_qualification;
|
2009-02-08 12:28:15 +00:00
|
|
|
int size, in, string;
|
2007-03-20 10:46:50 +00:00
|
|
|
unsigned port;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2007-09-12 06:18:28 +00:00
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
2007-03-20 10:46:50 +00:00
|
|
|
string = (exit_qualification & 16) != 0;
|
2010-03-18 13:20:23 +00:00
|
|
|
in = (exit_qualification & 8) != 0;
|
2007-08-05 07:36:40 +00:00
|
|
|
|
2010-03-18 13:20:23 +00:00
|
|
|
++vcpu->stat.io_exits;
|
2007-08-05 07:36:40 +00:00
|
|
|
|
2010-03-18 13:20:23 +00:00
|
|
|
if (string || in)
|
2010-12-21 10:12:02 +00:00
|
|
|
return emulate_instruction(vcpu, 0) == EMULATE_DONE;
|
2007-08-05 07:36:40 +00:00
|
|
|
|
2010-03-18 13:20:23 +00:00
|
|
|
port = exit_qualification >> 16;
|
|
|
|
size = (exit_qualification & 7) + 1;
|
2008-10-28 09:51:30 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
2010-03-18 13:20:23 +00:00
|
|
|
|
|
|
|
return kvm_fast_pio_out(vcpu, size, port);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 12:37:47 +00:00
|
|
|
static void
|
|
|
|
vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Patch in the VMCALL instruction:
|
|
|
|
*/
|
|
|
|
hypercall[0] = 0x0f;
|
|
|
|
hypercall[1] = 0x01;
|
|
|
|
hypercall[2] = 0xc1;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
static bool nested_cr0_valid(struct kvm_vcpu *vcpu, unsigned long val)
|
2013-08-08 14:26:33 +00:00
|
|
|
{
|
|
|
|
unsigned long always_on = VMXON_CR0_ALWAYSON;
|
2015-02-03 15:56:30 +00:00
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
2013-08-08 14:26:33 +00:00
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
if (to_vmx(vcpu)->nested.nested_vmx_secondary_ctls_high &
|
2013-08-08 14:26:33 +00:00
|
|
|
SECONDARY_EXEC_UNRESTRICTED_GUEST &&
|
|
|
|
nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST))
|
|
|
|
always_on &= ~(X86_CR0_PE | X86_CR0_PG);
|
|
|
|
return (val & always_on) == always_on;
|
|
|
|
}
|
|
|
|
|
2012-06-28 07:16:19 +00:00
|
|
|
/* called to set cr0 as appropriate for a mov-to-cr0 exit. */
|
2011-05-25 20:14:38 +00:00
|
|
|
static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val)
|
|
|
|
{
|
|
|
|
if (is_guest_mode(vcpu)) {
|
2013-03-07 13:08:07 +00:00
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
unsigned long orig_val = val;
|
|
|
|
|
2011-05-25 20:14:38 +00:00
|
|
|
/*
|
|
|
|
* We get here when L2 changed cr0 in a way that did not change
|
|
|
|
* any of L1's shadowed bits (see nested_vmx_exit_handled_cr),
|
2013-03-07 13:08:07 +00:00
|
|
|
* but did change L0 shadowed bits. So we first calculate the
|
|
|
|
* effective cr0 value that L1 would like to write into the
|
|
|
|
* hardware. It consists of the L2-owned bits from the new
|
|
|
|
* value combined with the L1-owned bits from L1's guest_cr0.
|
2011-05-25 20:14:38 +00:00
|
|
|
*/
|
2013-03-07 13:08:07 +00:00
|
|
|
val = (val & ~vmcs12->cr0_guest_host_mask) |
|
|
|
|
(vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask);
|
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
if (!nested_cr0_valid(vcpu, val))
|
2011-05-25 20:14:38 +00:00
|
|
|
return 1;
|
2013-03-07 13:08:07 +00:00
|
|
|
|
|
|
|
if (kvm_set_cr0(vcpu, val))
|
|
|
|
return 1;
|
|
|
|
vmcs_writel(CR0_READ_SHADOW, orig_val);
|
2011-05-25 20:14:38 +00:00
|
|
|
return 0;
|
2013-03-07 13:08:07 +00:00
|
|
|
} else {
|
|
|
|
if (to_vmx(vcpu)->nested.vmxon &&
|
|
|
|
((val & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON))
|
|
|
|
return 1;
|
2011-05-25 20:14:38 +00:00
|
|
|
return kvm_set_cr0(vcpu, val);
|
2013-03-07 13:08:07 +00:00
|
|
|
}
|
2011-05-25 20:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int handle_set_cr4(struct kvm_vcpu *vcpu, unsigned long val)
|
|
|
|
{
|
|
|
|
if (is_guest_mode(vcpu)) {
|
2013-03-07 13:08:07 +00:00
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
unsigned long orig_val = val;
|
|
|
|
|
|
|
|
/* analogously to handle_set_cr0 */
|
|
|
|
val = (val & ~vmcs12->cr4_guest_host_mask) |
|
|
|
|
(vmcs12->guest_cr4 & vmcs12->cr4_guest_host_mask);
|
|
|
|
if (kvm_set_cr4(vcpu, val))
|
2011-05-25 20:14:38 +00:00
|
|
|
return 1;
|
2013-03-07 13:08:07 +00:00
|
|
|
vmcs_writel(CR4_READ_SHADOW, orig_val);
|
2011-05-25 20:14:38 +00:00
|
|
|
return 0;
|
|
|
|
} else
|
|
|
|
return kvm_set_cr4(vcpu, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* called to set cr0 as approriate for clts instruction exit. */
|
|
|
|
static void handle_clts(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
if (is_guest_mode(vcpu)) {
|
|
|
|
/*
|
|
|
|
* We get here when L2 did CLTS, and L1 didn't shadow CR0.TS
|
|
|
|
* but we did (!fpu_active). We need to keep GUEST_CR0.TS on,
|
|
|
|
* just pretend it's off (also in arch.cr0 for fpu_activate).
|
|
|
|
*/
|
|
|
|
vmcs_writel(CR0_READ_SHADOW,
|
|
|
|
vmcs_readl(CR0_READ_SHADOW) & ~X86_CR0_TS);
|
|
|
|
vcpu->arch.cr0 &= ~X86_CR0_TS;
|
|
|
|
} else
|
|
|
|
vmx_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_cr(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2009-06-17 12:22:14 +00:00
|
|
|
unsigned long exit_qualification, val;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
int cr;
|
|
|
|
int reg;
|
2010-06-10 14:02:14 +00:00
|
|
|
int err;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2007-09-12 06:18:28 +00:00
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
cr = exit_qualification & 15;
|
|
|
|
reg = (exit_qualification >> 8) & 15;
|
|
|
|
switch ((exit_qualification >> 4) & 3) {
|
|
|
|
case 0: /* mov to cr */
|
2014-06-18 14:19:25 +00:00
|
|
|
val = kvm_register_readl(vcpu, reg);
|
2009-06-17 12:22:14 +00:00
|
|
|
trace_kvm_cr_write(cr, val);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
switch (cr) {
|
|
|
|
case 0:
|
2011-05-25 20:14:38 +00:00
|
|
|
err = handle_set_cr0(vcpu, val);
|
2010-12-21 10:12:01 +00:00
|
|
|
kvm_complete_insn_gp(vcpu, err);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
|
|
|
case 3:
|
2010-06-10 14:02:16 +00:00
|
|
|
err = kvm_set_cr3(vcpu, val);
|
2010-12-21 10:12:01 +00:00
|
|
|
kvm_complete_insn_gp(vcpu, err);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
|
|
|
case 4:
|
2011-05-25 20:14:38 +00:00
|
|
|
err = handle_set_cr4(vcpu, val);
|
2010-12-21 10:12:01 +00:00
|
|
|
kvm_complete_insn_gp(vcpu, err);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
2009-04-21 14:45:06 +00:00
|
|
|
case 8: {
|
|
|
|
u8 cr8_prev = kvm_get_cr8(vcpu);
|
2014-06-18 14:19:25 +00:00
|
|
|
u8 cr8 = (u8)val;
|
2010-12-21 10:12:00 +00:00
|
|
|
err = kvm_set_cr8(vcpu, cr8);
|
2010-12-21 10:12:01 +00:00
|
|
|
kvm_complete_insn_gp(vcpu, err);
|
2015-07-29 10:05:37 +00:00
|
|
|
if (lapic_in_kernel(vcpu))
|
2009-04-21 14:45:06 +00:00
|
|
|
return 1;
|
|
|
|
if (cr8_prev <= cr8)
|
|
|
|
return 1;
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_SET_TPR;
|
2009-04-21 14:45:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2012-09-18 16:36:14 +00:00
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
break;
|
2007-04-27 06:29:21 +00:00
|
|
|
case 2: /* clts */
|
2011-05-25 20:14:38 +00:00
|
|
|
handle_clts(vcpu);
|
2009-12-29 16:07:30 +00:00
|
|
|
trace_kvm_cr_write(0, kvm_read_cr0(vcpu));
|
2007-04-27 06:29:21 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
2010-01-21 13:31:47 +00:00
|
|
|
vmx_fpu_activate(vcpu);
|
2007-04-27 06:29:21 +00:00
|
|
|
return 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
case 1: /*mov from cr*/
|
|
|
|
switch (cr) {
|
|
|
|
case 3:
|
2010-12-05 15:30:00 +00:00
|
|
|
val = kvm_read_cr3(vcpu);
|
|
|
|
kvm_register_write(vcpu, reg, val);
|
|
|
|
trace_kvm_cr_read(cr, val);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
case 8:
|
2009-06-17 12:22:14 +00:00
|
|
|
val = kvm_get_cr8(vcpu);
|
|
|
|
kvm_register_write(vcpu, reg, val);
|
|
|
|
trace_kvm_cr_read(cr, val);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3: /* lmsw */
|
2009-12-29 15:33:58 +00:00
|
|
|
val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f;
|
2009-12-29 16:07:30 +00:00
|
|
|
trace_kvm_cr_write(0, (kvm_read_cr0(vcpu) & ~0xful) | val);
|
2009-12-29 15:33:58 +00:00
|
|
|
kvm_lmsw(vcpu, val);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->exit_reason = 0;
|
KVM: Cleanup the kvm_print functions and introduce pr_XX wrappers
Introduces a couple of print functions, which are essentially wrappers
around standard printk functions, with a KVM: prefix.
Functions introduced or modified are:
- kvm_err(fmt, ...)
- kvm_info(fmt, ...)
- kvm_debug(fmt, ...)
- kvm_pr_unimpl(fmt, ...)
- pr_unimpl(vcpu, fmt, ...) -> vcpu_unimpl(vcpu, fmt, ...)
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2012-06-03 18:17:48 +00:00
|
|
|
vcpu_unimpl(vcpu, "unhandled control register: op %d cr %d\n",
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
(int)(exit_qualification >> 4) & 3, cr);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_dr(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-09-12 06:18:28 +00:00
|
|
|
unsigned long exit_qualification;
|
2014-10-02 22:10:05 +00:00
|
|
|
int dr, dr7, reg;
|
|
|
|
|
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
dr = exit_qualification & DEBUG_REG_ACCESS_NUM;
|
|
|
|
|
|
|
|
/* First, if DR does not exist, trigger UD */
|
|
|
|
if (!kvm_require_dr(vcpu, dr))
|
|
|
|
return 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2010-01-20 17:20:20 +00:00
|
|
|
/* Do not handle if the CPL > 0, will trigger GP on re-entry */
|
2009-09-01 09:03:25 +00:00
|
|
|
if (!kvm_require_cpl(vcpu, 0))
|
|
|
|
return 1;
|
2014-10-02 22:10:05 +00:00
|
|
|
dr7 = vmcs_readl(GUEST_DR7);
|
|
|
|
if (dr7 & DR7_GD) {
|
2008-12-15 12:52:10 +00:00
|
|
|
/*
|
|
|
|
* As the vm-exit takes precedence over the debug trap, we
|
|
|
|
* need to emulate the latter, either for the host or the
|
|
|
|
* guest debugging itself.
|
|
|
|
*/
|
|
|
|
if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->debug.arch.dr6 = vcpu->arch.dr6;
|
2014-10-02 22:10:05 +00:00
|
|
|
vcpu->run->debug.arch.dr7 = dr7;
|
2014-11-02 09:54:45 +00:00
|
|
|
vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu);
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->debug.arch.exception = DB_VECTOR;
|
|
|
|
vcpu->run->exit_reason = KVM_EXIT_DEBUG;
|
2008-12-15 12:52:10 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
2014-11-02 09:54:44 +00:00
|
|
|
vcpu->arch.dr6 &= ~15;
|
2014-07-15 14:37:46 +00:00
|
|
|
vcpu->arch.dr6 |= DR6_BD | DR6_RTM;
|
2008-12-15 12:52:10 +00:00
|
|
|
kvm_queue_exception(vcpu, DB_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-21 09:32:27 +00:00
|
|
|
if (vcpu->guest_debug == 0) {
|
|
|
|
u32 cpu_based_vm_exec_control;
|
|
|
|
|
|
|
|
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
cpu_based_vm_exec_control &= ~CPU_BASED_MOV_DR_EXITING;
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* No more DR vmexits; force a reload of the debug registers
|
|
|
|
* and reenter on this instruction. The next vmexit will
|
|
|
|
* retrieve the full state of the debug registers.
|
|
|
|
*/
|
|
|
|
vcpu->arch.switch_db_regs |= KVM_DEBUGREG_WONT_EXIT;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-12-15 12:52:10 +00:00
|
|
|
reg = DEBUG_REG_ACCESS_REG(exit_qualification);
|
|
|
|
if (exit_qualification & TYPE_MOV_FROM_DR) {
|
2010-04-13 07:05:23 +00:00
|
|
|
unsigned long val;
|
2013-12-18 18:16:24 +00:00
|
|
|
|
|
|
|
if (kvm_get_dr(vcpu, dr, &val))
|
|
|
|
return 1;
|
|
|
|
kvm_register_write(vcpu, reg, val);
|
2010-04-13 07:05:23 +00:00
|
|
|
} else
|
2014-06-18 14:19:23 +00:00
|
|
|
if (kvm_set_dr(vcpu, dr, kvm_register_readl(vcpu, reg)))
|
2013-12-18 18:16:24 +00:00
|
|
|
return 1;
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-01-04 17:47:16 +00:00
|
|
|
static u64 vmx_get_dr6(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return vcpu->arch.dr6;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-02-21 09:32:27 +00:00
|
|
|
static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u32 cpu_based_vm_exec_control;
|
|
|
|
|
|
|
|
get_debugreg(vcpu->arch.db[0], 0);
|
|
|
|
get_debugreg(vcpu->arch.db[1], 1);
|
|
|
|
get_debugreg(vcpu->arch.db[2], 2);
|
|
|
|
get_debugreg(vcpu->arch.db[3], 3);
|
|
|
|
get_debugreg(vcpu->arch.dr6, 6);
|
|
|
|
vcpu->arch.dr7 = vmcs_readl(GUEST_DR7);
|
|
|
|
|
|
|
|
vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_WONT_EXIT;
|
|
|
|
|
|
|
|
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
cpu_based_vm_exec_control |= CPU_BASED_MOV_DR_EXITING;
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
|
|
|
|
}
|
|
|
|
|
2010-04-13 07:05:23 +00:00
|
|
|
static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
|
|
|
|
{
|
|
|
|
vmcs_writel(GUEST_DR7, val);
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_cpuid(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-02-28 18:46:53 +00:00
|
|
|
kvm_emulate_cpuid(vcpu);
|
|
|
|
return 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_rdmsr(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-12-13 15:50:52 +00:00
|
|
|
u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
|
2015-04-08 13:30:38 +00:00
|
|
|
struct msr_data msr_info;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info.index = ecx;
|
|
|
|
msr_info.host_initiated = false;
|
|
|
|
if (vmx_get_msr(vcpu, &msr_info)) {
|
2010-01-25 17:47:02 +00:00
|
|
|
trace_kvm_msr_read_ex(ecx);
|
2007-11-25 12:12:03 +00:00
|
|
|
kvm_inject_gp(vcpu, 0);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-08 13:30:38 +00:00
|
|
|
trace_kvm_msr_read(ecx, msr_info.data);
|
2008-04-10 19:31:10 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* FIXME: handling of bits 32:63 of rax, rdx */
|
2015-04-08 13:30:38 +00:00
|
|
|
vcpu->arch.regs[VCPU_REGS_RAX] = msr_info.data & -1u;
|
|
|
|
vcpu->arch.regs[VCPU_REGS_RDX] = (msr_info.data >> 32) & -1u;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_wrmsr(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2012-11-29 20:42:12 +00:00
|
|
|
struct msr_data msr;
|
2007-12-13 15:50:52 +00:00
|
|
|
u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
|
|
|
|
u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
|
|
|
|
| ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2012-11-29 20:42:12 +00:00
|
|
|
msr.data = data;
|
|
|
|
msr.index = ecx;
|
|
|
|
msr.host_initiated = false;
|
KVM: x86: Check non-canonical addresses upon WRMSR
Upon WRMSR, the CPU should inject #GP if a non-canonical value (address) is
written to certain MSRs. The behavior is "almost" identical for AMD and Intel
(ignoring MSRs that are not implemented in either architecture since they would
anyhow #GP). However, IA32_SYSENTER_ESP and IA32_SYSENTER_EIP cause #GP if
non-canonical address is written on Intel but not on AMD (which ignores the top
32-bits).
Accordingly, this patch injects a #GP on the MSRs which behave identically on
Intel and AMD. To eliminate the differences between the architecutres, the
value which is written to IA32_SYSENTER_ESP and IA32_SYSENTER_EIP is turned to
canonical value before writing instead of injecting a #GP.
Some references from Intel and AMD manuals:
According to Intel SDM description of WRMSR instruction #GP is expected on
WRMSR "If the source register contains a non-canonical address and ECX
specifies one of the following MSRs: IA32_DS_AREA, IA32_FS_BASE, IA32_GS_BASE,
IA32_KERNEL_GS_BASE, IA32_LSTAR, IA32_SYSENTER_EIP, IA32_SYSENTER_ESP."
According to AMD manual instruction manual:
LSTAR/CSTAR (SYSCALL): "The WRMSR instruction loads the target RIP into the
LSTAR and CSTAR registers. If an RIP written by WRMSR is not in canonical
form, a general-protection exception (#GP) occurs."
IA32_GS_BASE and IA32_FS_BASE (WRFSBASE/WRGSBASE): "The address written to the
base field must be in canonical form or a #GP fault will occur."
IA32_KERNEL_GS_BASE (SWAPGS): "The address stored in the KernelGSbase MSR must
be in canonical form."
This patch fixes CVE-2014-3610.
Cc: stable@vger.kernel.org
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-16 00:24:05 +00:00
|
|
|
if (kvm_set_msr(vcpu, &msr) != 0) {
|
2010-01-25 17:47:02 +00:00
|
|
|
trace_kvm_msr_write_ex(ecx, data);
|
2007-11-25 12:12:03 +00:00
|
|
|
kvm_inject_gp(vcpu, 0);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-01-25 17:47:02 +00:00
|
|
|
trace_kvm_msr_write(ecx, data);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu)
|
2007-09-12 10:03:11 +00:00
|
|
|
{
|
2010-07-27 09:30:24 +00:00
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
2007-09-12 10:03:11 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_interrupt_window(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-07-06 09:20:49 +00:00
|
|
|
u32 cpu_based_vm_exec_control;
|
|
|
|
|
|
|
|
/* clear pending irq */
|
|
|
|
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
|
2008-04-10 19:31:10 +00:00
|
|
|
|
2010-07-27 09:30:24 +00:00
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
|
|
|
|
2008-09-26 07:30:45 +00:00
|
|
|
++vcpu->stat.irq_window_exits;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_halt(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-06-05 12:53:05 +00:00
|
|
|
return kvm_emulate_halt(vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_vmcall(struct kvm_vcpu *vcpu)
|
2007-02-19 12:37:47 +00:00
|
|
|
{
|
2007-09-17 19:57:50 +00:00
|
|
|
kvm_emulate_hypercall(vcpu);
|
|
|
|
return 1;
|
2007-02-19 12:37:47 +00:00
|
|
|
}
|
|
|
|
|
2010-11-01 13:35:01 +00:00
|
|
|
static int handle_invd(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2010-12-21 10:12:02 +00:00
|
|
|
return emulate_instruction(vcpu, 0) == EMULATE_DONE;
|
2010-11-01 13:35:01 +00:00
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_invlpg(struct kvm_vcpu *vcpu)
|
2008-09-23 16:18:35 +00:00
|
|
|
{
|
2009-03-25 02:08:52 +00:00
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
2008-09-23 16:18:35 +00:00
|
|
|
|
|
|
|
kvm_mmu_invlpg(vcpu, exit_qualification);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-11-10 12:57:25 +00:00
|
|
|
static int handle_rdpmc(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kvm_rdpmc(vcpu);
|
|
|
|
kvm_complete_insn_gp(vcpu, err);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_wbinvd(struct kvm_vcpu *vcpu)
|
2007-11-11 10:28:35 +00:00
|
|
|
{
|
2010-06-30 04:25:15 +00:00
|
|
|
kvm_emulate_wbinvd(vcpu);
|
2007-11-11 10:28:35 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-06-10 03:27:12 +00:00
|
|
|
static int handle_xsetbv(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u64 new_bv = kvm_read_edx_eax(vcpu);
|
|
|
|
u32 index = kvm_register_read(vcpu, VCPU_REGS_RCX);
|
|
|
|
|
|
|
|
if (kvm_set_xcr(vcpu, index, new_bv) == 0)
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-12-02 11:14:58 +00:00
|
|
|
static int handle_xsaves(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
WARN(1, "this should never happen\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int handle_xrstors(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
WARN(1, "this should never happen\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_apic_access(struct kvm_vcpu *vcpu)
|
2007-10-29 01:40:42 +00:00
|
|
|
{
|
2011-08-30 10:56:17 +00:00
|
|
|
if (likely(fasteoi)) {
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
int access_type, offset;
|
|
|
|
|
|
|
|
access_type = exit_qualification & APIC_ACCESS_TYPE;
|
|
|
|
offset = exit_qualification & APIC_ACCESS_OFFSET;
|
|
|
|
/*
|
|
|
|
* Sane guest uses MOV to write EOI, with written value
|
|
|
|
* not cared. So make a short-circuit here by avoiding
|
|
|
|
* heavy instruction emulation.
|
|
|
|
*/
|
|
|
|
if ((access_type == TYPE_LINEAR_APIC_INST_WRITE) &&
|
|
|
|
(offset == APIC_EOI)) {
|
|
|
|
kvm_lapic_set_eoi(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2010-12-21 10:12:02 +00:00
|
|
|
return emulate_instruction(vcpu, 0) == EMULATE_DONE;
|
2007-10-29 01:40:42 +00:00
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:51 +00:00
|
|
|
static int handle_apic_eoi_induced(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
int vector = exit_qualification & 0xff;
|
|
|
|
|
|
|
|
/* EOI-induced VM exit is trap-like and thus no need to adjust IP */
|
|
|
|
kvm_apic_set_eoi_accelerated(vcpu, vector);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:49 +00:00
|
|
|
static int handle_apic_write(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
u32 offset = exit_qualification & 0xfff;
|
|
|
|
|
|
|
|
/* APIC-write VM exit is trap-like and thus no need to adjust IP */
|
|
|
|
kvm_apic_write_nodecode(vcpu, offset);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_task_switch(struct kvm_vcpu *vcpu)
|
2008-03-24 21:14:53 +00:00
|
|
|
{
|
2008-09-26 07:30:47 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2008-03-24 21:14:53 +00:00
|
|
|
unsigned long exit_qualification;
|
2010-04-14 13:51:09 +00:00
|
|
|
bool has_error_code = false;
|
|
|
|
u32 error_code = 0;
|
2008-03-24 21:14:53 +00:00
|
|
|
u16 tss_selector;
|
2012-02-08 13:34:38 +00:00
|
|
|
int reason, type, idt_v, idt_index;
|
2009-03-30 13:03:29 +00:00
|
|
|
|
|
|
|
idt_v = (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
|
2012-02-08 13:34:38 +00:00
|
|
|
idt_index = (vmx->idt_vectoring_info & VECTORING_INFO_VECTOR_MASK);
|
2009-03-30 13:03:29 +00:00
|
|
|
type = (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK);
|
2008-03-24 21:14:53 +00:00
|
|
|
|
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
|
|
|
|
reason = (u32)exit_qualification >> 30;
|
2009-03-30 13:03:29 +00:00
|
|
|
if (reason == TASK_SWITCH_GATE && idt_v) {
|
|
|
|
switch (type) {
|
|
|
|
case INTR_TYPE_NMI_INTR:
|
|
|
|
vcpu->arch.nmi_injected = false;
|
2011-03-23 13:02:47 +00:00
|
|
|
vmx_set_nmi_mask(vcpu, true);
|
2009-03-30 13:03:29 +00:00
|
|
|
break;
|
|
|
|
case INTR_TYPE_EXT_INTR:
|
2009-05-11 10:35:50 +00:00
|
|
|
case INTR_TYPE_SOFT_INTR:
|
2009-03-30 13:03:29 +00:00
|
|
|
kvm_clear_interrupt_queue(vcpu);
|
|
|
|
break;
|
|
|
|
case INTR_TYPE_HARD_EXCEPTION:
|
2010-04-14 13:51:09 +00:00
|
|
|
if (vmx->idt_vectoring_info &
|
|
|
|
VECTORING_INFO_DELIVER_CODE_MASK) {
|
|
|
|
has_error_code = true;
|
|
|
|
error_code =
|
|
|
|
vmcs_read32(IDT_VECTORING_ERROR_CODE);
|
|
|
|
}
|
|
|
|
/* fall through */
|
2009-03-30 13:03:29 +00:00
|
|
|
case INTR_TYPE_SOFT_EXCEPTION:
|
|
|
|
kvm_clear_exception_queue(vcpu);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2008-09-26 07:30:47 +00:00
|
|
|
}
|
2008-03-24 21:14:53 +00:00
|
|
|
tss_selector = exit_qualification;
|
|
|
|
|
2009-03-30 13:03:29 +00:00
|
|
|
if (!idt_v || (type != INTR_TYPE_HARD_EXCEPTION &&
|
|
|
|
type != INTR_TYPE_EXT_INTR &&
|
|
|
|
type != INTR_TYPE_NMI_INTR))
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
|
2012-02-08 13:34:38 +00:00
|
|
|
if (kvm_task_switch(vcpu, tss_selector,
|
|
|
|
type == INTR_TYPE_SOFT_INTR ? idt_index : -1, reason,
|
|
|
|
has_error_code, error_code) == EMULATE_FAIL) {
|
2010-04-15 18:03:50 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
|
|
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
|
|
|
vcpu->run->internal.ndata = 0;
|
2008-12-15 12:52:10 +00:00
|
|
|
return 0;
|
2010-04-15 18:03:50 +00:00
|
|
|
}
|
2008-12-15 12:52:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: What about debug traps on tss switch?
|
|
|
|
* Are we supposed to inject them and update dr6?
|
|
|
|
*/
|
|
|
|
|
|
|
|
return 1;
|
2008-03-24 21:14:53 +00:00
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_ept_violation(struct kvm_vcpu *vcpu)
|
2008-04-28 04:24:45 +00:00
|
|
|
{
|
2009-03-25 02:08:52 +00:00
|
|
|
unsigned long exit_qualification;
|
2008-04-28 04:24:45 +00:00
|
|
|
gpa_t gpa;
|
2012-06-20 07:58:04 +00:00
|
|
|
u32 error_code;
|
2008-04-28 04:24:45 +00:00
|
|
|
int gla_validity;
|
|
|
|
|
2009-03-25 02:08:52 +00:00
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
2008-04-28 04:24:45 +00:00
|
|
|
|
|
|
|
gla_validity = (exit_qualification >> 7) & 0x3;
|
|
|
|
if (gla_validity != 0x3 && gla_validity != 0x1 && gla_validity != 0) {
|
|
|
|
printk(KERN_ERR "EPT: Handling EPT violation failed!\n");
|
|
|
|
printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n",
|
|
|
|
(long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS),
|
2009-03-25 02:08:52 +00:00
|
|
|
vmcs_readl(GUEST_LINEAR_ADDRESS));
|
2008-04-28 04:24:45 +00:00
|
|
|
printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
|
|
|
|
(long unsigned int)exit_qualification);
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
|
|
|
|
vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_VIOLATION;
|
2009-06-03 11:12:10 +00:00
|
|
|
return 0;
|
2008-04-28 04:24:45 +00:00
|
|
|
}
|
|
|
|
|
2013-09-15 08:07:23 +00:00
|
|
|
/*
|
|
|
|
* EPT violation happened while executing iret from NMI,
|
|
|
|
* "blocked by NMI" bit has to be set before next VM entry.
|
|
|
|
* There are errata that may cause this bit to not be set:
|
|
|
|
* AAK134, BY25.
|
|
|
|
*/
|
2013-09-25 07:58:22 +00:00
|
|
|
if (!(to_vmx(vcpu)->idt_vectoring_info & VECTORING_INFO_VALID_MASK) &&
|
|
|
|
cpu_has_virtual_nmis() &&
|
|
|
|
(exit_qualification & INTR_INFO_UNBLOCK_NMI))
|
2013-09-15 08:07:23 +00:00
|
|
|
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, GUEST_INTR_STATE_NMI);
|
|
|
|
|
2008-04-28 04:24:45 +00:00
|
|
|
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
2009-06-17 12:22:14 +00:00
|
|
|
trace_kvm_page_fault(gpa, exit_qualification);
|
2012-06-20 07:58:04 +00:00
|
|
|
|
|
|
|
/* It is a write fault? */
|
2014-11-18 09:12:56 +00:00
|
|
|
error_code = exit_qualification & PFERR_WRITE_MASK;
|
2013-08-06 09:00:32 +00:00
|
|
|
/* It is a fetch fault? */
|
2014-11-18 09:12:56 +00:00
|
|
|
error_code |= (exit_qualification << 2) & PFERR_FETCH_MASK;
|
2012-06-20 07:58:04 +00:00
|
|
|
/* ept page table is present? */
|
2014-11-18 09:12:56 +00:00
|
|
|
error_code |= (exit_qualification >> 3) & PFERR_PRESENT_MASK;
|
2012-06-20 07:58:04 +00:00
|
|
|
|
2013-08-06 09:00:32 +00:00
|
|
|
vcpu->arch.exit_qualification = exit_qualification;
|
|
|
|
|
2012-06-20 07:58:04 +00:00
|
|
|
return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
|
2008-04-28 04:24:45 +00:00
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
|
2009-06-11 15:07:43 +00:00
|
|
|
{
|
2015-08-05 04:04:27 +00:00
|
|
|
int ret;
|
2009-06-11 15:07:43 +00:00
|
|
|
gpa_t gpa;
|
|
|
|
|
|
|
|
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
2015-03-26 14:39:28 +00:00
|
|
|
if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) {
|
KVM: VMX: speed up wildcard MMIO EVENTFD
With KVM, MMIO is much slower than PIO, due to the need to
do page walk and emulation. But with EPT, it does not have to be: we
know the address from the VMCS so if the address is unique, we can look
up the eventfd directly, bypassing emulation.
Unfortunately, this only works if userspace does not need to match on
access length and data. The implementation adds a separate FAST_MMIO
bus internally. This serves two purposes:
- minimize overhead for old userspace that does not use eventfd with lengtth = 0
- minimize disruption in other code (since we don't know the length,
devices on the MMIO bus only get a valid address in write, this
way we don't need to touch all devices to teach them to handle
an invalid length)
At the moment, this optimization only has effect for EPT on x86.
It will be possible to speed up MMIO for NPT and MMU using the same
idea in the future.
With this patch applied, on VMX MMIO EVENTFD is essentially as fast as PIO.
I was unable to detect any measureable slowdown to non-eventfd MMIO.
Making MMIO faster is important for the upcoming virtio 1.0 which
includes an MMIO signalling capability.
The idea was suggested by Peter Anvin. Lots of thanks to Gleb for
pre-review and suggestions.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2014-03-31 18:50:44 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
2015-09-15 06:41:58 +00:00
|
|
|
trace_kvm_fast_mmio(gpa);
|
KVM: VMX: speed up wildcard MMIO EVENTFD
With KVM, MMIO is much slower than PIO, due to the need to
do page walk and emulation. But with EPT, it does not have to be: we
know the address from the VMCS so if the address is unique, we can look
up the eventfd directly, bypassing emulation.
Unfortunately, this only works if userspace does not need to match on
access length and data. The implementation adds a separate FAST_MMIO
bus internally. This serves two purposes:
- minimize overhead for old userspace that does not use eventfd with lengtth = 0
- minimize disruption in other code (since we don't know the length,
devices on the MMIO bus only get a valid address in write, this
way we don't need to touch all devices to teach them to handle
an invalid length)
At the moment, this optimization only has effect for EPT on x86.
It will be possible to speed up MMIO for NPT and MMU using the same
idea in the future.
With this patch applied, on VMX MMIO EVENTFD is essentially as fast as PIO.
I was unable to detect any measureable slowdown to non-eventfd MMIO.
Making MMIO faster is important for the upcoming virtio 1.0 which
includes an MMIO signalling capability.
The idea was suggested by Peter Anvin. Lots of thanks to Gleb for
pre-review and suggestions.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2014-03-31 18:50:44 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2009-06-11 15:07:43 +00:00
|
|
|
|
2011-07-11 19:33:44 +00:00
|
|
|
ret = handle_mmio_page_fault_common(vcpu, gpa, true);
|
2013-06-07 08:51:25 +00:00
|
|
|
if (likely(ret == RET_MMIO_PF_EMULATE))
|
2011-07-11 19:33:44 +00:00
|
|
|
return x86_emulate_instruction(vcpu, gpa, 0, NULL, 0) ==
|
|
|
|
EMULATE_DONE;
|
2013-06-07 08:51:26 +00:00
|
|
|
|
|
|
|
if (unlikely(ret == RET_MMIO_PF_INVALID))
|
|
|
|
return kvm_mmu_page_fault(vcpu, gpa, 0, NULL, 0);
|
|
|
|
|
2013-06-07 08:51:25 +00:00
|
|
|
if (unlikely(ret == RET_MMIO_PF_RETRY))
|
2011-07-11 19:33:44 +00:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* It is the real ept misconfig */
|
2015-08-05 04:04:27 +00:00
|
|
|
WARN_ON(1);
|
2009-06-11 15:07:43 +00:00
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
|
|
|
|
vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
|
2009-06-11 15:07:43 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-24 08:10:17 +00:00
|
|
|
static int handle_nmi_window(struct kvm_vcpu *vcpu)
|
2008-05-15 10:23:25 +00:00
|
|
|
{
|
|
|
|
u32 cpu_based_vm_exec_control;
|
|
|
|
|
|
|
|
/* clear pending NMI */
|
|
|
|
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
|
|
|
|
++vcpu->stat.nmi_window_exits;
|
2010-07-27 09:30:24 +00:00
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
2008-05-15 10:23:25 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-09-01 10:48:18 +00:00
|
|
|
static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
|
2008-08-17 13:47:05 +00:00
|
|
|
{
|
2009-01-05 10:10:54 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
enum emulation_result err = EMULATE_DONE;
|
2009-09-01 10:48:18 +00:00
|
|
|
int ret = 1;
|
2010-09-19 12:34:08 +00:00
|
|
|
u32 cpu_exec_ctrl;
|
|
|
|
bool intr_window_requested;
|
2012-06-07 14:08:48 +00:00
|
|
|
unsigned count = 130;
|
2010-09-19 12:34:08 +00:00
|
|
|
|
|
|
|
cpu_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
intr_window_requested = cpu_exec_ctrl & CPU_BASED_VIRTUAL_INTR_PENDING;
|
2008-08-17 13:47:05 +00:00
|
|
|
|
2014-03-27 08:51:52 +00:00
|
|
|
while (vmx->emulation_required && count-- != 0) {
|
2012-06-10 15:07:57 +00:00
|
|
|
if (intr_window_requested && vmx_interrupt_allowed(vcpu))
|
2010-09-19 12:34:08 +00:00
|
|
|
return handle_interrupt_window(&vmx->vcpu);
|
|
|
|
|
2012-06-12 17:21:38 +00:00
|
|
|
if (test_bit(KVM_REQ_EVENT, &vcpu->requests))
|
|
|
|
return 1;
|
|
|
|
|
2013-04-11 09:10:51 +00:00
|
|
|
err = emulate_instruction(vcpu, EMULTYPE_NO_REEXECUTE);
|
2008-08-17 13:47:05 +00:00
|
|
|
|
2013-06-25 16:24:41 +00:00
|
|
|
if (err == EMULATE_USER_EXIT) {
|
2013-08-27 13:41:42 +00:00
|
|
|
++vcpu->stat.mmio_exits;
|
2009-09-01 10:48:18 +00:00
|
|
|
ret = 0;
|
|
|
|
goto out;
|
|
|
|
}
|
2008-10-29 08:39:42 +00:00
|
|
|
|
2012-06-12 17:22:28 +00:00
|
|
|
if (err != EMULATE_DONE) {
|
|
|
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
|
|
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
|
|
|
vcpu->run->internal.ndata = 0;
|
2010-05-10 08:16:56 +00:00
|
|
|
return 0;
|
2012-06-12 17:22:28 +00:00
|
|
|
}
|
2008-08-17 13:47:05 +00:00
|
|
|
|
2013-05-08 15:38:44 +00:00
|
|
|
if (vcpu->arch.halt_request) {
|
|
|
|
vcpu->arch.halt_request = 0;
|
2015-03-02 19:43:31 +00:00
|
|
|
ret = kvm_vcpu_halt(vcpu);
|
2013-05-08 15:38:44 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2008-08-17 13:47:05 +00:00
|
|
|
if (signal_pending(current))
|
2009-09-01 10:48:18 +00:00
|
|
|
goto out;
|
2008-08-17 13:47:05 +00:00
|
|
|
if (need_resched())
|
|
|
|
schedule();
|
|
|
|
}
|
|
|
|
|
2009-09-01 10:48:18 +00:00
|
|
|
out:
|
|
|
|
return ret;
|
2008-08-17 13:47:05 +00:00
|
|
|
}
|
|
|
|
|
2014-08-21 16:08:08 +00:00
|
|
|
static int __grow_ple_window(int val)
|
|
|
|
{
|
|
|
|
if (ple_window_grow < 1)
|
|
|
|
return ple_window;
|
|
|
|
|
|
|
|
val = min(val, ple_window_actual_max);
|
|
|
|
|
|
|
|
if (ple_window_grow < ple_window)
|
|
|
|
val *= ple_window_grow;
|
|
|
|
else
|
|
|
|
val += ple_window_grow;
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __shrink_ple_window(int val, int modifier, int minimum)
|
|
|
|
{
|
|
|
|
if (modifier < 1)
|
|
|
|
return ple_window;
|
|
|
|
|
|
|
|
if (modifier < ple_window)
|
|
|
|
val /= modifier;
|
|
|
|
else
|
|
|
|
val -= modifier;
|
|
|
|
|
|
|
|
return max(val, minimum);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void grow_ple_window(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int old = vmx->ple_window;
|
|
|
|
|
|
|
|
vmx->ple_window = __grow_ple_window(old);
|
|
|
|
|
|
|
|
if (vmx->ple_window != old)
|
|
|
|
vmx->ple_window_dirty = true;
|
2014-08-21 16:08:09 +00:00
|
|
|
|
|
|
|
trace_kvm_ple_window_grow(vcpu->vcpu_id, vmx->ple_window, old);
|
2014-08-21 16:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void shrink_ple_window(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int old = vmx->ple_window;
|
|
|
|
|
|
|
|
vmx->ple_window = __shrink_ple_window(old,
|
|
|
|
ple_window_shrink, ple_window);
|
|
|
|
|
|
|
|
if (vmx->ple_window != old)
|
|
|
|
vmx->ple_window_dirty = true;
|
2014-08-21 16:08:09 +00:00
|
|
|
|
|
|
|
trace_kvm_ple_window_shrink(vcpu->vcpu_id, vmx->ple_window, old);
|
2014-08-21 16:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ple_window_actual_max is computed to be one grow_ple_window() below
|
|
|
|
* ple_window_max. (See __grow_ple_window for the reason.)
|
|
|
|
* This prevents overflows, because ple_window_max is int.
|
|
|
|
* ple_window_max effectively rounded down to a multiple of ple_window_grow in
|
|
|
|
* this process.
|
|
|
|
* ple_window_max is also prevented from setting vmx->ple_window < ple_window.
|
|
|
|
*/
|
|
|
|
static void update_ple_window_actual_max(void)
|
|
|
|
{
|
|
|
|
ple_window_actual_max =
|
|
|
|
__shrink_ple_window(max(ple_window_max, ple_window),
|
|
|
|
ple_window_grow, INT_MIN);
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:14:47 +00:00
|
|
|
static __init int hardware_setup(void)
|
|
|
|
{
|
2014-10-28 02:14:48 +00:00
|
|
|
int r = -ENOMEM, i, msr;
|
|
|
|
|
|
|
|
rdmsrl_safe(MSR_EFER, &host_efer);
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i)
|
|
|
|
kvm_define_shared_msr(i, vmx_msr_index[i]);
|
|
|
|
|
|
|
|
vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_io_bitmap_a)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_io_bitmap_b)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_msr_bitmap_legacy)
|
|
|
|
goto out1;
|
|
|
|
|
|
|
|
vmx_msr_bitmap_legacy_x2apic =
|
|
|
|
(unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_msr_bitmap_legacy_x2apic)
|
|
|
|
goto out2;
|
|
|
|
|
|
|
|
vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_msr_bitmap_longmode)
|
|
|
|
goto out3;
|
|
|
|
|
|
|
|
vmx_msr_bitmap_longmode_x2apic =
|
|
|
|
(unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_msr_bitmap_longmode_x2apic)
|
|
|
|
goto out4;
|
2015-02-03 15:49:31 +00:00
|
|
|
|
|
|
|
if (nested) {
|
|
|
|
vmx_msr_bitmap_nested =
|
|
|
|
(unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_msr_bitmap_nested)
|
|
|
|
goto out5;
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:14:48 +00:00
|
|
|
vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_vmread_bitmap)
|
2015-02-03 15:49:31 +00:00
|
|
|
goto out6;
|
2014-10-28 02:14:48 +00:00
|
|
|
|
|
|
|
vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
|
|
|
|
if (!vmx_vmwrite_bitmap)
|
2015-02-03 15:49:31 +00:00
|
|
|
goto out7;
|
2014-10-28 02:14:48 +00:00
|
|
|
|
|
|
|
memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
|
|
|
|
memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allow direct access to the PC debug port (it is often used for I/O
|
|
|
|
* delays, but the vmexits simply slow things down).
|
|
|
|
*/
|
|
|
|
memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
|
|
|
|
clear_bit(0x80, vmx_io_bitmap_a);
|
|
|
|
|
|
|
|
memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
|
|
|
|
|
|
|
|
memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
|
|
|
|
memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
|
2015-02-03 15:49:31 +00:00
|
|
|
if (nested)
|
|
|
|
memset(vmx_msr_bitmap_nested, 0xff, PAGE_SIZE);
|
2014-10-28 02:14:48 +00:00
|
|
|
|
|
|
|
if (setup_vmcs_config(&vmcs_config) < 0) {
|
|
|
|
r = -EIO;
|
2015-02-03 15:49:31 +00:00
|
|
|
goto out8;
|
2014-12-23 08:21:11 +00:00
|
|
|
}
|
2014-10-28 02:14:47 +00:00
|
|
|
|
|
|
|
if (boot_cpu_has(X86_FEATURE_NX))
|
|
|
|
kvm_enable_efer_bits(EFER_NX);
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_vpid())
|
|
|
|
enable_vpid = 0;
|
|
|
|
if (!cpu_has_vmx_shadow_vmcs())
|
|
|
|
enable_shadow_vmcs = 0;
|
|
|
|
if (enable_shadow_vmcs)
|
|
|
|
init_vmcs_shadow_fields();
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_ept() ||
|
|
|
|
!cpu_has_vmx_ept_4levels()) {
|
|
|
|
enable_ept = 0;
|
|
|
|
enable_unrestricted_guest = 0;
|
|
|
|
enable_ept_ad_bits = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_ept_ad_bits())
|
|
|
|
enable_ept_ad_bits = 0;
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_unrestricted_guest())
|
|
|
|
enable_unrestricted_guest = 0;
|
|
|
|
|
2015-01-30 15:18:49 +00:00
|
|
|
if (!cpu_has_vmx_flexpriority())
|
2014-10-28 02:14:47 +00:00
|
|
|
flexpriority_enabled = 0;
|
|
|
|
|
2015-01-30 15:18:49 +00:00
|
|
|
/*
|
|
|
|
* set_apic_access_page_addr() is used to reload apic access
|
|
|
|
* page upon invalidation. No need to do anything if not
|
|
|
|
* using the APIC_ACCESS_ADDR VMCS field.
|
|
|
|
*/
|
|
|
|
if (!flexpriority_enabled)
|
2014-10-28 02:14:47 +00:00
|
|
|
kvm_x86_ops->set_apic_access_page_addr = NULL;
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_tpr_shadow())
|
|
|
|
kvm_x86_ops->update_cr8_intercept = NULL;
|
|
|
|
|
|
|
|
if (enable_ept && !cpu_has_vmx_ept_2m_page())
|
|
|
|
kvm_disable_largepages();
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_ple())
|
|
|
|
ple_gap = 0;
|
|
|
|
|
|
|
|
if (!cpu_has_vmx_apicv())
|
|
|
|
enable_apicv = 0;
|
|
|
|
|
|
|
|
if (enable_apicv)
|
|
|
|
kvm_x86_ops->update_cr8_intercept = NULL;
|
|
|
|
else {
|
|
|
|
kvm_x86_ops->hwapic_irr_update = NULL;
|
2014-12-22 09:32:57 +00:00
|
|
|
kvm_x86_ops->hwapic_isr_update = NULL;
|
2014-10-28 02:14:47 +00:00
|
|
|
kvm_x86_ops->deliver_posted_interrupt = NULL;
|
|
|
|
kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
|
|
|
|
}
|
|
|
|
|
2014-12-23 08:21:11 +00:00
|
|
|
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
|
|
|
|
vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
|
|
|
|
vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
|
|
|
|
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
|
|
|
|
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
|
|
|
|
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
|
|
|
|
vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
|
|
|
|
|
|
|
|
memcpy(vmx_msr_bitmap_legacy_x2apic,
|
|
|
|
vmx_msr_bitmap_legacy, PAGE_SIZE);
|
|
|
|
memcpy(vmx_msr_bitmap_longmode_x2apic,
|
|
|
|
vmx_msr_bitmap_longmode, PAGE_SIZE);
|
|
|
|
|
2015-09-16 11:31:11 +00:00
|
|
|
set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
|
|
|
|
|
2014-12-23 08:21:11 +00:00
|
|
|
if (enable_apicv) {
|
|
|
|
for (msr = 0x800; msr <= 0x8ff; msr++)
|
|
|
|
vmx_disable_intercept_msr_read_x2apic(msr);
|
|
|
|
|
|
|
|
/* According SDM, in x2apic mode, the whole id reg is used.
|
|
|
|
* But in KVM, it only use the highest eight bits. Need to
|
|
|
|
* intercept it */
|
|
|
|
vmx_enable_intercept_msr_read_x2apic(0x802);
|
|
|
|
/* TMCCT */
|
|
|
|
vmx_enable_intercept_msr_read_x2apic(0x839);
|
|
|
|
/* TPR */
|
|
|
|
vmx_disable_intercept_msr_write_x2apic(0x808);
|
|
|
|
/* EOI */
|
|
|
|
vmx_disable_intercept_msr_write_x2apic(0x80b);
|
|
|
|
/* SELF-IPI */
|
|
|
|
vmx_disable_intercept_msr_write_x2apic(0x83f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (enable_ept) {
|
|
|
|
kvm_mmu_set_mask_ptes(0ull,
|
|
|
|
(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
|
|
|
|
(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
|
|
|
|
0ull, VMX_EPT_EXECUTABLE_MASK);
|
|
|
|
ept_set_mmio_spte_mask();
|
|
|
|
kvm_enable_tdp();
|
|
|
|
} else
|
|
|
|
kvm_disable_tdp();
|
|
|
|
|
|
|
|
update_ple_window_actual_max();
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
/*
|
|
|
|
* Only enable PML when hardware supports PML feature, and both EPT
|
|
|
|
* and EPT A/D bit features are enabled -- PML depends on them to work.
|
|
|
|
*/
|
|
|
|
if (!enable_ept || !enable_ept_ad_bits || !cpu_has_vmx_pml())
|
|
|
|
enable_pml = 0;
|
|
|
|
|
|
|
|
if (!enable_pml) {
|
|
|
|
kvm_x86_ops->slot_enable_log_dirty = NULL;
|
|
|
|
kvm_x86_ops->slot_disable_log_dirty = NULL;
|
|
|
|
kvm_x86_ops->flush_log_dirty = NULL;
|
|
|
|
kvm_x86_ops->enable_log_dirty_pt_masked = NULL;
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:14:47 +00:00
|
|
|
return alloc_kvm_area();
|
2014-10-28 02:14:48 +00:00
|
|
|
|
2015-02-03 15:49:31 +00:00
|
|
|
out8:
|
2014-10-28 02:14:48 +00:00
|
|
|
free_page((unsigned long)vmx_vmwrite_bitmap);
|
2015-02-03 15:49:31 +00:00
|
|
|
out7:
|
2014-10-28 02:14:48 +00:00
|
|
|
free_page((unsigned long)vmx_vmread_bitmap);
|
2015-02-03 15:49:31 +00:00
|
|
|
out6:
|
|
|
|
if (nested)
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_nested);
|
2014-10-28 02:14:48 +00:00
|
|
|
out5:
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
|
|
|
|
out4:
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_longmode);
|
|
|
|
out3:
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
|
|
|
|
out2:
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_legacy);
|
|
|
|
out1:
|
|
|
|
free_page((unsigned long)vmx_io_bitmap_b);
|
|
|
|
out:
|
|
|
|
free_page((unsigned long)vmx_io_bitmap_a);
|
|
|
|
|
|
|
|
return r;
|
2014-10-28 02:14:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static __exit void hardware_unsetup(void)
|
|
|
|
{
|
2014-10-28 02:14:48 +00:00
|
|
|
free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_legacy);
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_longmode);
|
|
|
|
free_page((unsigned long)vmx_io_bitmap_b);
|
|
|
|
free_page((unsigned long)vmx_io_bitmap_a);
|
|
|
|
free_page((unsigned long)vmx_vmwrite_bitmap);
|
|
|
|
free_page((unsigned long)vmx_vmread_bitmap);
|
2015-02-03 15:49:31 +00:00
|
|
|
if (nested)
|
|
|
|
free_page((unsigned long)vmx_msr_bitmap_nested);
|
2014-10-28 02:14:48 +00:00
|
|
|
|
2014-10-28 02:14:47 +00:00
|
|
|
free_kvm_area();
|
|
|
|
}
|
|
|
|
|
2009-10-09 10:03:20 +00:00
|
|
|
/*
|
|
|
|
* Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE
|
|
|
|
* exiting, so only get here on cpu with PAUSE-Loop-Exiting.
|
|
|
|
*/
|
2009-10-12 22:37:31 +00:00
|
|
|
static int handle_pause(struct kvm_vcpu *vcpu)
|
2009-10-09 10:03:20 +00:00
|
|
|
{
|
2014-08-21 16:08:08 +00:00
|
|
|
if (ple_gap)
|
|
|
|
grow_ple_window(vcpu);
|
|
|
|
|
2009-10-09 10:03:20 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
kvm_vcpu_on_spin(vcpu);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-05-07 20:52:13 +00:00
|
|
|
static int handle_nop(struct kvm_vcpu *vcpu)
|
2009-12-15 05:29:54 +00:00
|
|
|
{
|
2014-05-07 20:52:13 +00:00
|
|
|
skip_emulated_instruction(vcpu);
|
2009-12-15 05:29:54 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-05-07 20:52:13 +00:00
|
|
|
static int handle_mwait(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
printk_once(KERN_WARNING "kvm: MWAIT instruction emulated as NOP!\n");
|
|
|
|
return handle_nop(vcpu);
|
|
|
|
}
|
|
|
|
|
2015-07-05 17:08:57 +00:00
|
|
|
static int handle_monitor_trap(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-05-07 20:52:13 +00:00
|
|
|
static int handle_monitor(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
printk_once(KERN_WARNING "kvm: MONITOR instruction emulated as NOP!\n");
|
|
|
|
return handle_nop(vcpu);
|
|
|
|
}
|
|
|
|
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
/*
|
|
|
|
* To run an L2 guest, we need a vmcs02 based on the L1-specified vmcs12.
|
|
|
|
* We could reuse a single VMCS for all the L2 guests, but we also want the
|
|
|
|
* option to allocate a separate vmcs02 for each separate loaded vmcs12 - this
|
|
|
|
* allows keeping them loaded on the processor, and in the future will allow
|
|
|
|
* optimizations where prepare_vmcs02 doesn't need to set all the fields on
|
|
|
|
* every entry if they never change.
|
|
|
|
* So we keep, in vmx->nested.vmcs02_pool, a cache of size VMCS02_POOL_SIZE
|
|
|
|
* (>=0) with a vmcs02 for each recently loaded vmcs12s, most recent first.
|
|
|
|
*
|
|
|
|
* The following functions allocate and free a vmcs02 in this pool.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Get a VMCS from the pool to use as vmcs02 for the current vmcs12. */
|
|
|
|
static struct loaded_vmcs *nested_get_current_vmcs02(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
struct vmcs02_list *item;
|
|
|
|
list_for_each_entry(item, &vmx->nested.vmcs02_pool, list)
|
|
|
|
if (item->vmptr == vmx->nested.current_vmptr) {
|
|
|
|
list_move(&item->list, &vmx->nested.vmcs02_pool);
|
|
|
|
return &item->vmcs02;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vmx->nested.vmcs02_num >= max(VMCS02_POOL_SIZE, 1)) {
|
|
|
|
/* Recycle the least recently used VMCS. */
|
|
|
|
item = list_entry(vmx->nested.vmcs02_pool.prev,
|
|
|
|
struct vmcs02_list, list);
|
|
|
|
item->vmptr = vmx->nested.current_vmptr;
|
|
|
|
list_move(&item->list, &vmx->nested.vmcs02_pool);
|
|
|
|
return &item->vmcs02;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a new VMCS */
|
2013-03-10 13:46:00 +00:00
|
|
|
item = kmalloc(sizeof(struct vmcs02_list), GFP_KERNEL);
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
if (!item)
|
|
|
|
return NULL;
|
|
|
|
item->vmcs02.vmcs = alloc_vmcs();
|
|
|
|
if (!item->vmcs02.vmcs) {
|
|
|
|
kfree(item);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
loaded_vmcs_init(&item->vmcs02);
|
|
|
|
item->vmptr = vmx->nested.current_vmptr;
|
|
|
|
list_add(&(item->list), &(vmx->nested.vmcs02_pool));
|
|
|
|
vmx->nested.vmcs02_num++;
|
|
|
|
return &item->vmcs02;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free and remove from pool a vmcs02 saved for a vmcs12 (if there is one) */
|
|
|
|
static void nested_free_vmcs02(struct vcpu_vmx *vmx, gpa_t vmptr)
|
|
|
|
{
|
|
|
|
struct vmcs02_list *item;
|
|
|
|
list_for_each_entry(item, &vmx->nested.vmcs02_pool, list)
|
|
|
|
if (item->vmptr == vmptr) {
|
|
|
|
free_loaded_vmcs(&item->vmcs02);
|
|
|
|
list_del(&item->list);
|
|
|
|
kfree(item);
|
|
|
|
vmx->nested.vmcs02_num--;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free all VMCSs saved for this vcpu, except the one pointed by
|
2014-07-17 10:25:16 +00:00
|
|
|
* vmx->loaded_vmcs. We must be running L1, so vmx->loaded_vmcs
|
|
|
|
* must be &vmx->vmcs01.
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
*/
|
|
|
|
static void nested_free_all_saved_vmcss(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
struct vmcs02_list *item, *n;
|
2014-07-17 10:25:16 +00:00
|
|
|
|
|
|
|
WARN_ON(vmx->loaded_vmcs != &vmx->vmcs01);
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
list_for_each_entry_safe(item, n, &vmx->nested.vmcs02_pool, list) {
|
2014-07-17 10:25:16 +00:00
|
|
|
/*
|
|
|
|
* Something will leak if the above WARN triggers. Better than
|
|
|
|
* a use-after-free.
|
|
|
|
*/
|
|
|
|
if (vmx->loaded_vmcs == &item->vmcs02)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
free_loaded_vmcs(&item->vmcs02);
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
list_del(&item->list);
|
|
|
|
kfree(item);
|
2014-07-17 10:25:16 +00:00
|
|
|
vmx->nested.vmcs02_num--;
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-04 07:03:32 +00:00
|
|
|
/*
|
|
|
|
* The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(),
|
|
|
|
* set the success or error code of an emulated VMX instruction, as specified
|
|
|
|
* by Vol 2B, VMX Instruction Reference, "Conventions".
|
|
|
|
*/
|
|
|
|
static void nested_vmx_succeed(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
vmx_set_rflags(vcpu, vmx_get_rflags(vcpu)
|
|
|
|
& ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
|
|
|
|
X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nested_vmx_failInvalid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
|
|
|
|
& ~(X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF |
|
|
|
|
X86_EFLAGS_SF | X86_EFLAGS_OF))
|
|
|
|
| X86_EFLAGS_CF);
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:36:55 +00:00
|
|
|
static void nested_vmx_failValid(struct kvm_vcpu *vcpu,
|
2013-07-04 07:03:32 +00:00
|
|
|
u32 vm_instruction_error)
|
|
|
|
{
|
|
|
|
if (to_vmx(vcpu)->nested.current_vmptr == -1ull) {
|
|
|
|
/*
|
|
|
|
* failValid writes the error number to the current VMCS, which
|
|
|
|
* can't be done there isn't a current VMCS.
|
|
|
|
*/
|
|
|
|
nested_vmx_failInvalid(vcpu);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu)
|
|
|
|
& ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
|
|
|
|
X86_EFLAGS_SF | X86_EFLAGS_OF))
|
|
|
|
| X86_EFLAGS_ZF);
|
|
|
|
get_vmcs12(vcpu)->vm_instruction_error = vm_instruction_error;
|
|
|
|
/*
|
|
|
|
* We don't need to force a shadow sync because
|
|
|
|
* VM_INSTRUCTION_ERROR is not shadowed
|
|
|
|
*/
|
|
|
|
}
|
2013-04-18 11:36:55 +00:00
|
|
|
|
2014-12-11 05:52:58 +00:00
|
|
|
static void nested_vmx_abort(struct kvm_vcpu *vcpu, u32 indicator)
|
|
|
|
{
|
|
|
|
/* TODO: not to reset guest simply here. */
|
|
|
|
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
|
|
|
pr_warn("kvm: nested vmx abort, indicator %d\n", indicator);
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
static enum hrtimer_restart vmx_preemption_timer_fn(struct hrtimer *timer)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx =
|
|
|
|
container_of(timer, struct vcpu_vmx, nested.preemption_timer);
|
|
|
|
|
|
|
|
vmx->nested.preemption_timer_expired = true;
|
|
|
|
kvm_make_request(KVM_REQ_EVENT, &vmx->vcpu);
|
|
|
|
kvm_vcpu_kick(&vmx->vcpu);
|
|
|
|
|
|
|
|
return HRTIMER_NORESTART;
|
|
|
|
}
|
|
|
|
|
2014-05-06 06:19:15 +00:00
|
|
|
/*
|
|
|
|
* Decode the memory-address operand of a vmx instruction, as recorded on an
|
|
|
|
* exit caused by such an instruction (run by a guest hypervisor).
|
|
|
|
* On success, returns 0. When the operand is invalid, returns 1 and throws
|
|
|
|
* #UD or #GP.
|
|
|
|
*/
|
|
|
|
static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
|
|
|
|
unsigned long exit_qualification,
|
2015-04-17 02:22:21 +00:00
|
|
|
u32 vmx_instruction_info, bool wr, gva_t *ret)
|
2014-05-06 06:19:15 +00:00
|
|
|
{
|
2015-04-17 02:22:21 +00:00
|
|
|
gva_t off;
|
|
|
|
bool exn;
|
|
|
|
struct kvm_segment s;
|
|
|
|
|
2014-05-06 06:19:15 +00:00
|
|
|
/*
|
|
|
|
* According to Vol. 3B, "Information for VM Exits Due to Instruction
|
|
|
|
* Execution", on an exit, vmx_instruction_info holds most of the
|
|
|
|
* addressing components of the operand. Only the displacement part
|
|
|
|
* is put in exit_qualification (see 3B, "Basic VM-Exit Information").
|
|
|
|
* For how an actual address is calculated from all these components,
|
|
|
|
* refer to Vol. 1, "Operand Addressing".
|
|
|
|
*/
|
|
|
|
int scaling = vmx_instruction_info & 3;
|
|
|
|
int addr_size = (vmx_instruction_info >> 7) & 7;
|
|
|
|
bool is_reg = vmx_instruction_info & (1u << 10);
|
|
|
|
int seg_reg = (vmx_instruction_info >> 15) & 7;
|
|
|
|
int index_reg = (vmx_instruction_info >> 18) & 0xf;
|
|
|
|
bool index_is_valid = !(vmx_instruction_info & (1u << 22));
|
|
|
|
int base_reg = (vmx_instruction_info >> 23) & 0xf;
|
|
|
|
bool base_is_valid = !(vmx_instruction_info & (1u << 27));
|
|
|
|
|
|
|
|
if (is_reg) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Addr = segment_base + offset */
|
|
|
|
/* offset = base + [index * scale] + displacement */
|
2015-04-17 02:22:21 +00:00
|
|
|
off = exit_qualification; /* holds the displacement */
|
2014-05-06 06:19:15 +00:00
|
|
|
if (base_is_valid)
|
2015-04-17 02:22:21 +00:00
|
|
|
off += kvm_register_read(vcpu, base_reg);
|
2014-05-06 06:19:15 +00:00
|
|
|
if (index_is_valid)
|
2015-04-17 02:22:21 +00:00
|
|
|
off += kvm_register_read(vcpu, index_reg)<<scaling;
|
|
|
|
vmx_get_segment(vcpu, &s, seg_reg);
|
|
|
|
*ret = s.base + off;
|
2014-05-06 06:19:15 +00:00
|
|
|
|
|
|
|
if (addr_size == 1) /* 32 bit */
|
|
|
|
*ret &= 0xffffffff;
|
|
|
|
|
2015-04-17 02:22:21 +00:00
|
|
|
/* Checks for #GP/#SS exceptions. */
|
|
|
|
exn = false;
|
|
|
|
if (is_protmode(vcpu)) {
|
|
|
|
/* Protected mode: apply checks for segment validity in the
|
|
|
|
* following order:
|
|
|
|
* - segment type check (#GP(0) may be thrown)
|
|
|
|
* - usability check (#GP(0)/#SS(0))
|
|
|
|
* - limit check (#GP(0)/#SS(0))
|
|
|
|
*/
|
|
|
|
if (wr)
|
|
|
|
/* #GP(0) if the destination operand is located in a
|
|
|
|
* read-only data segment or any code segment.
|
|
|
|
*/
|
|
|
|
exn = ((s.type & 0xa) == 0 || (s.type & 8));
|
|
|
|
else
|
|
|
|
/* #GP(0) if the source operand is located in an
|
|
|
|
* execute-only code segment
|
|
|
|
*/
|
|
|
|
exn = ((s.type & 0xa) == 8);
|
|
|
|
}
|
|
|
|
if (exn) {
|
|
|
|
kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (is_long_mode(vcpu)) {
|
|
|
|
/* Long mode: #GP(0)/#SS(0) if the memory address is in a
|
|
|
|
* non-canonical form. This is an only check for long mode.
|
|
|
|
*/
|
|
|
|
exn = is_noncanonical_address(*ret);
|
|
|
|
} else if (is_protmode(vcpu)) {
|
|
|
|
/* Protected mode: #GP(0)/#SS(0) if the segment is unusable.
|
|
|
|
*/
|
|
|
|
exn = (s.unusable != 0);
|
|
|
|
/* Protected mode: #GP(0)/#SS(0) if the memory
|
|
|
|
* operand is outside the segment limit.
|
|
|
|
*/
|
|
|
|
exn = exn || (off + sizeof(u64) > s.limit);
|
|
|
|
}
|
|
|
|
if (exn) {
|
|
|
|
kvm_queue_exception_e(vcpu,
|
|
|
|
seg_reg == VCPU_SREG_SS ?
|
|
|
|
SS_VECTOR : GP_VECTOR,
|
|
|
|
0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-05-06 06:19:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-05-06 06:19:16 +00:00
|
|
|
/*
|
|
|
|
* This function performs the various checks including
|
|
|
|
* - if it's 4KB aligned
|
|
|
|
* - No bits beyond the physical address width are set
|
|
|
|
* - Returns 0 on success or else 1
|
2014-05-06 06:19:18 +00:00
|
|
|
* (Intel SDM Section 30.3)
|
2014-05-06 06:19:16 +00:00
|
|
|
*/
|
2014-05-06 06:19:18 +00:00
|
|
|
static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason,
|
|
|
|
gpa_t *vmpointer)
|
2014-05-06 06:19:16 +00:00
|
|
|
{
|
|
|
|
gva_t gva;
|
|
|
|
gpa_t vmptr;
|
|
|
|
struct x86_exception e;
|
|
|
|
struct page *page;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int maxphyaddr = cpuid_maxphyaddr(vcpu);
|
|
|
|
|
|
|
|
if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION),
|
2015-04-17 02:22:21 +00:00
|
|
|
vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva))
|
2014-05-06 06:19:16 +00:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vmptr,
|
|
|
|
sizeof(vmptr), &e)) {
|
|
|
|
kvm_inject_page_fault(vcpu, &e);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (exit_reason) {
|
|
|
|
case EXIT_REASON_VMON:
|
|
|
|
/*
|
|
|
|
* SDM 3: 24.11.5
|
|
|
|
* The first 4 bytes of VMXON region contain the supported
|
|
|
|
* VMCS revision identifier
|
|
|
|
*
|
|
|
|
* Note - IA32_VMX_BASIC[48] will never be 1
|
|
|
|
* for the nested case;
|
|
|
|
* which replaces physical address width with 32
|
|
|
|
*
|
|
|
|
*/
|
2014-06-14 21:44:29 +00:00
|
|
|
if (!PAGE_ALIGNED(vmptr) || (vmptr >> maxphyaddr)) {
|
2014-05-06 06:19:16 +00:00
|
|
|
nested_vmx_failInvalid(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
page = nested_get_page(vcpu, vmptr);
|
|
|
|
if (page == NULL ||
|
|
|
|
*(u32 *)kmap(page) != VMCS12_REVISION) {
|
|
|
|
nested_vmx_failInvalid(vcpu);
|
|
|
|
kunmap(page);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
kunmap(page);
|
|
|
|
vmx->nested.vmxon_ptr = vmptr;
|
|
|
|
break;
|
2014-05-06 06:19:18 +00:00
|
|
|
case EXIT_REASON_VMCLEAR:
|
2014-06-14 21:44:29 +00:00
|
|
|
if (!PAGE_ALIGNED(vmptr) || (vmptr >> maxphyaddr)) {
|
2014-05-06 06:19:18 +00:00
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_VMCLEAR_INVALID_ADDRESS);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vmptr == vmx->nested.vmxon_ptr) {
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_VMCLEAR_VMXON_POINTER);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIT_REASON_VMPTRLD:
|
2014-06-14 21:44:29 +00:00
|
|
|
if (!PAGE_ALIGNED(vmptr) || (vmptr >> maxphyaddr)) {
|
2014-05-06 06:19:18 +00:00
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_VMPTRLD_INVALID_ADDRESS);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
2014-05-06 06:19:16 +00:00
|
|
|
|
2014-05-06 06:19:18 +00:00
|
|
|
if (vmptr == vmx->nested.vmxon_ptr) {
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_VMCLEAR_VMXON_POINTER);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
2014-05-06 06:19:16 +00:00
|
|
|
default:
|
|
|
|
return 1; /* shouldn't happen */
|
|
|
|
}
|
|
|
|
|
2014-05-06 06:19:18 +00:00
|
|
|
if (vmpointer)
|
|
|
|
*vmpointer = vmptr;
|
2014-05-06 06:19:16 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:02:54 +00:00
|
|
|
/*
|
|
|
|
* Emulate the VMXON instruction.
|
|
|
|
* Currently, we just remember that VMX is active, and do not save or even
|
|
|
|
* inspect the argument to VMXON (the so-called "VMXON pointer") because we
|
|
|
|
* do not currently need to store anything in that guest-allocated memory
|
|
|
|
* region. Consequently, VMCLEAR and VMPTRLD also do not verify that the their
|
|
|
|
* argument is different from the VMXON pointer (which the spec says they do).
|
|
|
|
*/
|
|
|
|
static int handle_vmon(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment cs;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2013-04-18 11:37:25 +00:00
|
|
|
struct vmcs *shadow_vmcs;
|
2013-07-08 11:12:35 +00:00
|
|
|
const u64 VMXON_NEEDED_FEATURES = FEATURE_CONTROL_LOCKED
|
|
|
|
| FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
2011-05-25 20:02:54 +00:00
|
|
|
|
|
|
|
/* The Intel VMX Instruction Reference lists a bunch of bits that
|
|
|
|
* are prerequisite to running VMXON, most notably cr4.VMXE must be
|
|
|
|
* set to 1 (see vmx_set_cr4() for when we allow the guest to set this).
|
|
|
|
* Otherwise, we should fail with #UD. We test these now:
|
|
|
|
*/
|
|
|
|
if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE) ||
|
|
|
|
!kvm_read_cr0_bits(vcpu, X86_CR0_PE) ||
|
|
|
|
(vmx_get_rflags(vcpu) & X86_EFLAGS_VM)) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
|
|
|
|
if (is_long_mode(vcpu) && !cs.l) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vmx_get_cpl(vcpu)) {
|
|
|
|
kvm_inject_gp(vcpu, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
2014-05-06 06:19:16 +00:00
|
|
|
|
2014-05-06 06:19:18 +00:00
|
|
|
if (nested_vmx_check_vmptr(vcpu, EXIT_REASON_VMON, NULL))
|
2014-05-06 06:19:16 +00:00
|
|
|
return 1;
|
|
|
|
|
2013-04-18 11:36:55 +00:00
|
|
|
if (vmx->nested.vmxon) {
|
|
|
|
nested_vmx_failValid(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
2013-07-08 11:12:35 +00:00
|
|
|
|
|
|
|
if ((vmx->nested.msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
|
|
|
|
!= VMXON_NEEDED_FEATURES) {
|
|
|
|
kvm_inject_gp(vcpu, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:37:25 +00:00
|
|
|
if (enable_shadow_vmcs) {
|
|
|
|
shadow_vmcs = alloc_vmcs();
|
|
|
|
if (!shadow_vmcs)
|
|
|
|
return -ENOMEM;
|
|
|
|
/* mark vmcs as shadow */
|
|
|
|
shadow_vmcs->revision_id |= (1u << 31);
|
|
|
|
/* init shadow vmcs */
|
|
|
|
vmcs_clear(shadow_vmcs);
|
|
|
|
vmx->nested.current_shadow_vmcs = shadow_vmcs;
|
|
|
|
}
|
2011-05-25 20:02:54 +00:00
|
|
|
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
INIT_LIST_HEAD(&(vmx->nested.vmcs02_pool));
|
|
|
|
vmx->nested.vmcs02_num = 0;
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
hrtimer_init(&vmx->nested.preemption_timer, CLOCK_MONOTONIC,
|
|
|
|
HRTIMER_MODE_REL);
|
|
|
|
vmx->nested.preemption_timer.function = vmx_preemption_timer_fn;
|
|
|
|
|
2011-05-25 20:02:54 +00:00
|
|
|
vmx->nested.vmxon = true;
|
|
|
|
|
|
|
|
skip_emulated_instruction(vcpu);
|
2013-07-04 07:03:33 +00:00
|
|
|
nested_vmx_succeed(vcpu);
|
2011-05-25 20:02:54 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Intel's VMX Instruction Reference specifies a common set of prerequisites
|
|
|
|
* for running VMX instructions (except VMXON, whose prerequisites are
|
|
|
|
* slightly different). It also specifies what exception to inject otherwise.
|
|
|
|
*/
|
|
|
|
static int nested_vmx_check_permission(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct kvm_segment cs;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
|
|
if (!vmx->nested.vmxon) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
|
|
|
|
if ((vmx_get_rflags(vcpu) & X86_EFLAGS_VM) ||
|
|
|
|
(is_long_mode(vcpu) && !cs.l)) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vmx_get_cpl(vcpu)) {
|
|
|
|
kvm_inject_gp(vcpu, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:37:55 +00:00
|
|
|
static inline void nested_release_vmcs12(struct vcpu_vmx *vmx)
|
|
|
|
{
|
2013-04-18 11:39:55 +00:00
|
|
|
u32 exec_control;
|
2014-07-17 09:55:46 +00:00
|
|
|
if (vmx->nested.current_vmptr == -1ull)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* current_vmptr and current_vmcs12 are always set/reset together */
|
|
|
|
if (WARN_ON(vmx->nested.current_vmcs12 == NULL))
|
|
|
|
return;
|
|
|
|
|
2013-04-18 11:39:25 +00:00
|
|
|
if (enable_shadow_vmcs) {
|
2014-07-17 09:55:46 +00:00
|
|
|
/* copy to memory all shadowed fields in case
|
|
|
|
they were modified */
|
|
|
|
copy_shadow_to_vmcs12(vmx);
|
|
|
|
vmx->nested.sync_shadow_vmcs = false;
|
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
|
|
|
|
vmcs_write64(VMCS_LINK_POINTER, -1ull);
|
2013-04-18 11:39:25 +00:00
|
|
|
}
|
2015-02-03 15:58:17 +00:00
|
|
|
vmx->nested.posted_intr_nv = -1;
|
2013-04-18 11:37:55 +00:00
|
|
|
kunmap(vmx->nested.current_vmcs12_page);
|
|
|
|
nested_release_page(vmx->nested.current_vmcs12_page);
|
2014-07-17 09:55:46 +00:00
|
|
|
vmx->nested.current_vmptr = -1ull;
|
|
|
|
vmx->nested.current_vmcs12 = NULL;
|
2013-04-18 11:37:55 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 20:02:54 +00:00
|
|
|
/*
|
|
|
|
* Free whatever needs to be freed from vmx->nested when L1 goes down, or
|
|
|
|
* just stops using VMX.
|
|
|
|
*/
|
|
|
|
static void free_nested(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
if (!vmx->nested.vmxon)
|
|
|
|
return;
|
2014-07-17 09:55:46 +00:00
|
|
|
|
2011-05-25 20:02:54 +00:00
|
|
|
vmx->nested.vmxon = false;
|
2014-07-17 09:55:46 +00:00
|
|
|
nested_release_vmcs12(vmx);
|
2013-04-18 11:37:55 +00:00
|
|
|
if (enable_shadow_vmcs)
|
|
|
|
free_vmcs(vmx->nested.current_shadow_vmcs);
|
2011-05-25 20:10:02 +00:00
|
|
|
/* Unpin physical memory we referred to in current vmcs02 */
|
|
|
|
if (vmx->nested.apic_access_page) {
|
|
|
|
nested_release_page(vmx->nested.apic_access_page);
|
2014-08-26 11:27:46 +00:00
|
|
|
vmx->nested.apic_access_page = NULL;
|
2011-05-25 20:10:02 +00:00
|
|
|
}
|
2014-08-21 11:46:50 +00:00
|
|
|
if (vmx->nested.virtual_apic_page) {
|
|
|
|
nested_release_page(vmx->nested.virtual_apic_page);
|
2014-08-26 11:27:46 +00:00
|
|
|
vmx->nested.virtual_apic_page = NULL;
|
2014-08-21 11:46:50 +00:00
|
|
|
}
|
2015-02-03 15:58:17 +00:00
|
|
|
if (vmx->nested.pi_desc_page) {
|
|
|
|
kunmap(vmx->nested.pi_desc_page);
|
|
|
|
nested_release_page(vmx->nested.pi_desc_page);
|
|
|
|
vmx->nested.pi_desc_page = NULL;
|
|
|
|
vmx->nested.pi_desc = NULL;
|
|
|
|
}
|
KVM: nVMX: Introduce vmcs02: VMCS used to run L2
We saw in a previous patch that L1 controls its L2 guest with a vcms12.
L0 needs to create a real VMCS for running L2. We call that "vmcs02".
A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
fields. This patch only contains code for allocating vmcs02.
In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
be reused even when L1 runs multiple L2 guests. However, in future versions
we'll probably want to add an optimization where vmcs02 fields that rarely
change will not be set each time. For that, we may want to keep around several
vmcs02s of L2 guests that have recently run, so that potentially we could run
these L2s again more quickly because less vmwrites to vmcs02 will be needed.
This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
reused to enter any L2 guest. In the future, when prepare_vmcs02() is
optimized not to set all fields every time, VMCS02_POOL_SIZE should be
increased.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:05:27 +00:00
|
|
|
|
|
|
|
nested_free_all_saved_vmcss(vmx);
|
2011-05-25 20:02:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Emulate the VMXOFF instruction */
|
|
|
|
static int handle_vmoff(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
if (!nested_vmx_check_permission(vcpu))
|
|
|
|
return 1;
|
|
|
|
free_nested(to_vmx(vcpu));
|
|
|
|
skip_emulated_instruction(vcpu);
|
2013-07-04 07:03:33 +00:00
|
|
|
nested_vmx_succeed(vcpu);
|
2011-05-25 20:02:54 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:06:59 +00:00
|
|
|
/* Emulate the VMCLEAR instruction */
|
|
|
|
static int handle_vmclear(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
gpa_t vmptr;
|
|
|
|
struct vmcs12 *vmcs12;
|
|
|
|
struct page *page;
|
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
2014-05-06 06:19:18 +00:00
|
|
|
if (nested_vmx_check_vmptr(vcpu, EXIT_REASON_VMCLEAR, &vmptr))
|
2011-05-25 20:06:59 +00:00
|
|
|
return 1;
|
|
|
|
|
2014-07-17 09:55:46 +00:00
|
|
|
if (vmptr == vmx->nested.current_vmptr)
|
2013-04-18 11:37:55 +00:00
|
|
|
nested_release_vmcs12(vmx);
|
2011-05-25 20:06:59 +00:00
|
|
|
|
|
|
|
page = nested_get_page(vcpu, vmptr);
|
|
|
|
if (page == NULL) {
|
|
|
|
/*
|
|
|
|
* For accurate processor emulation, VMCLEAR beyond available
|
|
|
|
* physical memory should do nothing at all. However, it is
|
|
|
|
* possible that a nested vmx bug, not a guest hypervisor bug,
|
|
|
|
* resulted in this case, so let's shut down before doing any
|
|
|
|
* more damage:
|
|
|
|
*/
|
|
|
|
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
vmcs12 = kmap(page);
|
|
|
|
vmcs12->launch_state = 0;
|
|
|
|
kunmap(page);
|
|
|
|
nested_release_page(page);
|
|
|
|
|
|
|
|
nested_free_vmcs02(vmx, vmptr);
|
|
|
|
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
nested_vmx_succeed(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:33 +00:00
|
|
|
static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch);
|
|
|
|
|
|
|
|
/* Emulate the VMLAUNCH instruction */
|
|
|
|
static int handle_vmlaunch(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return nested_vmx_run(vcpu, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Emulate the VMRESUME instruction */
|
|
|
|
static int handle_vmresume(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
|
|
|
|
return nested_vmx_run(vcpu, false);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:08:30 +00:00
|
|
|
enum vmcs_field_type {
|
|
|
|
VMCS_FIELD_TYPE_U16 = 0,
|
|
|
|
VMCS_FIELD_TYPE_U64 = 1,
|
|
|
|
VMCS_FIELD_TYPE_U32 = 2,
|
|
|
|
VMCS_FIELD_TYPE_NATURAL_WIDTH = 3
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline int vmcs_field_type(unsigned long field)
|
|
|
|
{
|
|
|
|
if (0x1 & field) /* the *_HIGH fields are all 32 bit */
|
|
|
|
return VMCS_FIELD_TYPE_U32;
|
|
|
|
return (field >> 13) & 0x3 ;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int vmcs_field_readonly(unsigned long field)
|
|
|
|
{
|
|
|
|
return (((field >> 10) & 0x3) == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read a vmcs12 field. Since these can have varying lengths and we return
|
|
|
|
* one type, we chose the biggest type (u64) and zero-extend the return value
|
|
|
|
* to that size. Note that the caller, handle_vmread, might need to use only
|
|
|
|
* some of the bits we return here (e.g., on 32-bit guests, only 32 bits of
|
|
|
|
* 64-bit fields are to be returned).
|
|
|
|
*/
|
2014-11-04 17:31:19 +00:00
|
|
|
static inline int vmcs12_read_any(struct kvm_vcpu *vcpu,
|
|
|
|
unsigned long field, u64 *ret)
|
2011-05-25 20:08:30 +00:00
|
|
|
{
|
|
|
|
short offset = vmcs_field_to_offset(field);
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
if (offset < 0)
|
2014-11-04 17:31:19 +00:00
|
|
|
return offset;
|
2011-05-25 20:08:30 +00:00
|
|
|
|
|
|
|
p = ((char *)(get_vmcs12(vcpu))) + offset;
|
|
|
|
|
|
|
|
switch (vmcs_field_type(field)) {
|
|
|
|
case VMCS_FIELD_TYPE_NATURAL_WIDTH:
|
|
|
|
*ret = *((natural_width *)p);
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2011-05-25 20:08:30 +00:00
|
|
|
case VMCS_FIELD_TYPE_U16:
|
|
|
|
*ret = *((u16 *)p);
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2011-05-25 20:08:30 +00:00
|
|
|
case VMCS_FIELD_TYPE_U32:
|
|
|
|
*ret = *((u32 *)p);
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2011-05-25 20:08:30 +00:00
|
|
|
case VMCS_FIELD_TYPE_U64:
|
|
|
|
*ret = *((u64 *)p);
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2011-05-25 20:08:30 +00:00
|
|
|
default:
|
2014-11-04 17:31:19 +00:00
|
|
|
WARN_ON(1);
|
|
|
|
return -ENOENT;
|
2011-05-25 20:08:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:36:25 +00:00
|
|
|
|
2014-11-04 17:31:19 +00:00
|
|
|
static inline int vmcs12_write_any(struct kvm_vcpu *vcpu,
|
|
|
|
unsigned long field, u64 field_value){
|
2013-04-18 11:36:25 +00:00
|
|
|
short offset = vmcs_field_to_offset(field);
|
|
|
|
char *p = ((char *) get_vmcs12(vcpu)) + offset;
|
|
|
|
if (offset < 0)
|
2014-11-04 17:31:19 +00:00
|
|
|
return offset;
|
2013-04-18 11:36:25 +00:00
|
|
|
|
|
|
|
switch (vmcs_field_type(field)) {
|
|
|
|
case VMCS_FIELD_TYPE_U16:
|
|
|
|
*(u16 *)p = field_value;
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2013-04-18 11:36:25 +00:00
|
|
|
case VMCS_FIELD_TYPE_U32:
|
|
|
|
*(u32 *)p = field_value;
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2013-04-18 11:36:25 +00:00
|
|
|
case VMCS_FIELD_TYPE_U64:
|
|
|
|
*(u64 *)p = field_value;
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2013-04-18 11:36:25 +00:00
|
|
|
case VMCS_FIELD_TYPE_NATURAL_WIDTH:
|
|
|
|
*(natural_width *)p = field_value;
|
2014-11-04 17:31:19 +00:00
|
|
|
return 0;
|
2013-04-18 11:36:25 +00:00
|
|
|
default:
|
2014-11-04 17:31:19 +00:00
|
|
|
WARN_ON(1);
|
|
|
|
return -ENOENT;
|
2013-04-18 11:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:38:25 +00:00
|
|
|
static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned long field;
|
|
|
|
u64 field_value;
|
|
|
|
struct vmcs *shadow_vmcs = vmx->nested.current_shadow_vmcs;
|
2013-06-26 18:36:21 +00:00
|
|
|
const unsigned long *fields = shadow_read_write_fields;
|
|
|
|
const int num_fields = max_shadow_read_write_fields;
|
2013-04-18 11:38:25 +00:00
|
|
|
|
2014-10-08 16:05:39 +00:00
|
|
|
preempt_disable();
|
|
|
|
|
2013-04-18 11:38:25 +00:00
|
|
|
vmcs_load(shadow_vmcs);
|
|
|
|
|
|
|
|
for (i = 0; i < num_fields; i++) {
|
|
|
|
field = fields[i];
|
|
|
|
switch (vmcs_field_type(field)) {
|
|
|
|
case VMCS_FIELD_TYPE_U16:
|
|
|
|
field_value = vmcs_read16(field);
|
|
|
|
break;
|
|
|
|
case VMCS_FIELD_TYPE_U32:
|
|
|
|
field_value = vmcs_read32(field);
|
|
|
|
break;
|
|
|
|
case VMCS_FIELD_TYPE_U64:
|
|
|
|
field_value = vmcs_read64(field);
|
|
|
|
break;
|
|
|
|
case VMCS_FIELD_TYPE_NATURAL_WIDTH:
|
|
|
|
field_value = vmcs_readl(field);
|
|
|
|
break;
|
2014-11-04 17:31:19 +00:00
|
|
|
default:
|
|
|
|
WARN_ON(1);
|
|
|
|
continue;
|
2013-04-18 11:38:25 +00:00
|
|
|
}
|
|
|
|
vmcs12_write_any(&vmx->vcpu, field, field_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
vmcs_clear(shadow_vmcs);
|
|
|
|
vmcs_load(vmx->loaded_vmcs->vmcs);
|
2014-10-08 16:05:39 +00:00
|
|
|
|
|
|
|
preempt_enable();
|
2013-04-18 11:38:25 +00:00
|
|
|
}
|
|
|
|
|
2013-04-18 11:38:55 +00:00
|
|
|
static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx)
|
|
|
|
{
|
2013-06-26 18:36:21 +00:00
|
|
|
const unsigned long *fields[] = {
|
|
|
|
shadow_read_write_fields,
|
|
|
|
shadow_read_only_fields
|
2013-04-18 11:38:55 +00:00
|
|
|
};
|
2013-06-26 18:36:21 +00:00
|
|
|
const int max_fields[] = {
|
2013-04-18 11:38:55 +00:00
|
|
|
max_shadow_read_write_fields,
|
|
|
|
max_shadow_read_only_fields
|
|
|
|
};
|
|
|
|
int i, q;
|
|
|
|
unsigned long field;
|
|
|
|
u64 field_value = 0;
|
|
|
|
struct vmcs *shadow_vmcs = vmx->nested.current_shadow_vmcs;
|
|
|
|
|
|
|
|
vmcs_load(shadow_vmcs);
|
|
|
|
|
2013-06-26 18:36:21 +00:00
|
|
|
for (q = 0; q < ARRAY_SIZE(fields); q++) {
|
2013-04-18 11:38:55 +00:00
|
|
|
for (i = 0; i < max_fields[q]; i++) {
|
|
|
|
field = fields[q][i];
|
|
|
|
vmcs12_read_any(&vmx->vcpu, field, &field_value);
|
|
|
|
|
|
|
|
switch (vmcs_field_type(field)) {
|
|
|
|
case VMCS_FIELD_TYPE_U16:
|
|
|
|
vmcs_write16(field, (u16)field_value);
|
|
|
|
break;
|
|
|
|
case VMCS_FIELD_TYPE_U32:
|
|
|
|
vmcs_write32(field, (u32)field_value);
|
|
|
|
break;
|
|
|
|
case VMCS_FIELD_TYPE_U64:
|
|
|
|
vmcs_write64(field, (u64)field_value);
|
|
|
|
break;
|
|
|
|
case VMCS_FIELD_TYPE_NATURAL_WIDTH:
|
|
|
|
vmcs_writel(field, (long)field_value);
|
|
|
|
break;
|
2014-11-04 17:31:19 +00:00
|
|
|
default:
|
|
|
|
WARN_ON(1);
|
|
|
|
break;
|
2013-04-18 11:38:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vmcs_clear(shadow_vmcs);
|
|
|
|
vmcs_load(vmx->loaded_vmcs->vmcs);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:08:30 +00:00
|
|
|
/*
|
|
|
|
* VMX instructions which assume a current vmcs12 (i.e., that VMPTRLD was
|
|
|
|
* used before) all generate the same failure when it is missing.
|
|
|
|
*/
|
|
|
|
static int nested_vmx_check_vmcs12(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
if (vmx->nested.current_vmptr == -1ull) {
|
|
|
|
nested_vmx_failInvalid(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int handle_vmread(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long field;
|
|
|
|
u64 field_value;
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
|
|
|
gva_t gva = 0;
|
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu) ||
|
|
|
|
!nested_vmx_check_vmcs12(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* Decode instruction info and find the field to read */
|
2014-06-18 14:19:26 +00:00
|
|
|
field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf));
|
2011-05-25 20:08:30 +00:00
|
|
|
/* Read the field, zero-extended to a u64 field_value */
|
2014-11-04 17:31:19 +00:00
|
|
|
if (vmcs12_read_any(vcpu, field, &field_value) < 0) {
|
2011-05-25 20:08:30 +00:00
|
|
|
nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Now copy part of this value to register or memory, as requested.
|
|
|
|
* Note that the number of bits actually copied is 32 or 64 depending
|
|
|
|
* on the guest's mode (32 or 64 bit), not on the given field's length.
|
|
|
|
*/
|
|
|
|
if (vmx_instruction_info & (1u << 10)) {
|
2014-06-18 14:19:26 +00:00
|
|
|
kvm_register_writel(vcpu, (((vmx_instruction_info) >> 3) & 0xf),
|
2011-05-25 20:08:30 +00:00
|
|
|
field_value);
|
|
|
|
} else {
|
|
|
|
if (get_vmx_mem_address(vcpu, exit_qualification,
|
2015-04-17 02:22:21 +00:00
|
|
|
vmx_instruction_info, true, &gva))
|
2011-05-25 20:08:30 +00:00
|
|
|
return 1;
|
|
|
|
/* _system ok, as nested_vmx_check_permission verified cpl=0 */
|
|
|
|
kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva,
|
|
|
|
&field_value, (is_long_mode(vcpu) ? 8 : 4), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
nested_vmx_succeed(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int handle_vmwrite(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long field;
|
|
|
|
gva_t gva;
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
|
|
|
/* The value to write might be 32 or 64 bits, depending on L1's long
|
|
|
|
* mode, and eventually we need to write that into a field of several
|
|
|
|
* possible lengths. The code below first zero-extends the value to 64
|
|
|
|
* bit (field_value), and then copies only the approriate number of
|
|
|
|
* bits into the vmcs12 field.
|
|
|
|
*/
|
|
|
|
u64 field_value = 0;
|
|
|
|
struct x86_exception e;
|
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu) ||
|
|
|
|
!nested_vmx_check_vmcs12(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (vmx_instruction_info & (1u << 10))
|
2014-06-18 14:19:26 +00:00
|
|
|
field_value = kvm_register_readl(vcpu,
|
2011-05-25 20:08:30 +00:00
|
|
|
(((vmx_instruction_info) >> 3) & 0xf));
|
|
|
|
else {
|
|
|
|
if (get_vmx_mem_address(vcpu, exit_qualification,
|
2015-04-17 02:22:21 +00:00
|
|
|
vmx_instruction_info, false, &gva))
|
2011-05-25 20:08:30 +00:00
|
|
|
return 1;
|
|
|
|
if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva,
|
2014-06-18 14:19:26 +00:00
|
|
|
&field_value, (is_64_bit_mode(vcpu) ? 8 : 4), &e)) {
|
2011-05-25 20:08:30 +00:00
|
|
|
kvm_inject_page_fault(vcpu, &e);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-18 14:19:26 +00:00
|
|
|
field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf));
|
2011-05-25 20:08:30 +00:00
|
|
|
if (vmcs_field_readonly(field)) {
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-11-04 17:31:19 +00:00
|
|
|
if (vmcs12_write_any(vcpu, field, field_value) < 0) {
|
2011-05-25 20:08:30 +00:00
|
|
|
nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
nested_vmx_succeed(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:07:29 +00:00
|
|
|
/* Emulate the VMPTRLD instruction */
|
|
|
|
static int handle_vmptrld(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
gpa_t vmptr;
|
2013-04-18 11:39:55 +00:00
|
|
|
u32 exec_control;
|
2011-05-25 20:07:29 +00:00
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
2014-05-06 06:19:18 +00:00
|
|
|
if (nested_vmx_check_vmptr(vcpu, EXIT_REASON_VMPTRLD, &vmptr))
|
2011-05-25 20:07:29 +00:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (vmx->nested.current_vmptr != vmptr) {
|
|
|
|
struct vmcs12 *new_vmcs12;
|
|
|
|
struct page *page;
|
|
|
|
page = nested_get_page(vcpu, vmptr);
|
|
|
|
if (page == NULL) {
|
|
|
|
nested_vmx_failInvalid(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
new_vmcs12 = kmap(page);
|
|
|
|
if (new_vmcs12->revision_id != VMCS12_REVISION) {
|
|
|
|
kunmap(page);
|
|
|
|
nested_release_page_clean(page);
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-07-17 09:55:46 +00:00
|
|
|
nested_release_vmcs12(vmx);
|
2011-05-25 20:07:29 +00:00
|
|
|
vmx->nested.current_vmptr = vmptr;
|
|
|
|
vmx->nested.current_vmcs12 = new_vmcs12;
|
|
|
|
vmx->nested.current_vmcs12_page = page;
|
2013-04-18 11:39:25 +00:00
|
|
|
if (enable_shadow_vmcs) {
|
2013-04-18 11:39:55 +00:00
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
exec_control |= SECONDARY_EXEC_SHADOW_VMCS;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
|
|
|
|
vmcs_write64(VMCS_LINK_POINTER,
|
|
|
|
__pa(vmx->nested.current_shadow_vmcs));
|
2013-04-18 11:39:25 +00:00
|
|
|
vmx->nested.sync_shadow_vmcs = true;
|
|
|
|
}
|
2011-05-25 20:07:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nested_vmx_succeed(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:08:00 +00:00
|
|
|
/* Emulate the VMPTRST instruction */
|
|
|
|
static int handle_vmptrst(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
|
|
|
gva_t vmcs_gva;
|
|
|
|
struct x86_exception e;
|
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (get_vmx_mem_address(vcpu, exit_qualification,
|
2015-04-17 02:22:21 +00:00
|
|
|
vmx_instruction_info, true, &vmcs_gva))
|
2011-05-25 20:08:00 +00:00
|
|
|
return 1;
|
|
|
|
/* ok to use *_system, as nested_vmx_check_permission verified cpl=0 */
|
|
|
|
if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva,
|
|
|
|
(void *)&to_vmx(vcpu)->nested.current_vmptr,
|
|
|
|
sizeof(u64), &e)) {
|
|
|
|
kvm_inject_page_fault(vcpu, &e);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
nested_vmx_succeed(vcpu);
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-08-05 08:07:17 +00:00
|
|
|
/* Emulate the INVEPT instruction */
|
|
|
|
static int handle_invept(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2015-02-03 15:56:30 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2013-08-05 08:07:17 +00:00
|
|
|
u32 vmx_instruction_info, types;
|
|
|
|
unsigned long type;
|
|
|
|
gva_t gva;
|
|
|
|
struct x86_exception e;
|
|
|
|
struct {
|
|
|
|
u64 eptp, gpa;
|
|
|
|
} operand;
|
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
if (!(vmx->nested.nested_vmx_secondary_ctls_high &
|
|
|
|
SECONDARY_EXEC_ENABLE_EPT) ||
|
|
|
|
!(vmx->nested.nested_vmx_ept_caps & VMX_EPT_INVEPT_BIT)) {
|
2013-08-05 08:07:17 +00:00
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (!kvm_read_cr0_bits(vcpu, X86_CR0_PE)) {
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
2014-06-18 14:19:26 +00:00
|
|
|
type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf);
|
2013-08-05 08:07:17 +00:00
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
types = (vmx->nested.nested_vmx_ept_caps >> VMX_EPT_EXTENT_SHIFT) & 6;
|
2013-08-05 08:07:17 +00:00
|
|
|
|
|
|
|
if (!(types & (1UL << type))) {
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* According to the Intel VMX instruction reference, the memory
|
|
|
|
* operand is read even if it isn't needed (e.g., for type==global)
|
|
|
|
*/
|
|
|
|
if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION),
|
2015-04-17 02:22:21 +00:00
|
|
|
vmx_instruction_info, false, &gva))
|
2013-08-05 08:07:17 +00:00
|
|
|
return 1;
|
|
|
|
if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand,
|
|
|
|
sizeof(operand), &e)) {
|
|
|
|
kvm_inject_page_fault(vcpu, &e);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case VMX_EPT_EXTENT_GLOBAL:
|
|
|
|
kvm_mmu_sync_roots(vcpu);
|
2014-09-18 16:38:37 +00:00
|
|
|
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
|
2013-08-05 08:07:17 +00:00
|
|
|
nested_vmx_succeed(vcpu);
|
|
|
|
break;
|
|
|
|
default:
|
2014-04-19 22:17:44 +00:00
|
|
|
/* Trap single context invalidation invept calls */
|
2013-08-05 08:07:17 +00:00
|
|
|
BUG_ON(1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-09-23 18:22:30 +00:00
|
|
|
static int handle_invvpid(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
static int handle_pml_full(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
unsigned long exit_qualification;
|
|
|
|
|
|
|
|
trace_kvm_pml_full(vcpu->vcpu_id);
|
|
|
|
|
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PML buffer FULL happened while executing iret from NMI,
|
|
|
|
* "blocked by NMI" bit has to be set before next VM entry.
|
|
|
|
*/
|
|
|
|
if (!(to_vmx(vcpu)->idt_vectoring_info & VECTORING_INFO_VALID_MASK) &&
|
|
|
|
cpu_has_virtual_nmis() &&
|
|
|
|
(exit_qualification & INTR_INFO_UNBLOCK_NMI))
|
|
|
|
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
|
|
|
|
GUEST_INTR_STATE_NMI);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PML buffer already flushed at beginning of VMEXIT. Nothing to do
|
|
|
|
* here.., and there's no userspace involvement needed for PML.
|
|
|
|
*/
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* The exit handlers return 1 if the exit was handled fully and guest execution
|
|
|
|
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
|
|
|
|
* to be done to userspace and return 0.
|
|
|
|
*/
|
2012-08-29 23:30:19 +00:00
|
|
|
static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
[EXIT_REASON_EXCEPTION_NMI] = handle_exception,
|
|
|
|
[EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
|
2007-02-12 08:54:36 +00:00
|
|
|
[EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault,
|
2008-05-15 10:23:25 +00:00
|
|
|
[EXIT_REASON_NMI_WINDOW] = handle_nmi_window,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
[EXIT_REASON_IO_INSTRUCTION] = handle_io,
|
|
|
|
[EXIT_REASON_CR_ACCESS] = handle_cr,
|
|
|
|
[EXIT_REASON_DR_ACCESS] = handle_dr,
|
|
|
|
[EXIT_REASON_CPUID] = handle_cpuid,
|
|
|
|
[EXIT_REASON_MSR_READ] = handle_rdmsr,
|
|
|
|
[EXIT_REASON_MSR_WRITE] = handle_wrmsr,
|
|
|
|
[EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window,
|
|
|
|
[EXIT_REASON_HLT] = handle_halt,
|
2010-11-01 13:35:01 +00:00
|
|
|
[EXIT_REASON_INVD] = handle_invd,
|
2008-09-23 16:18:35 +00:00
|
|
|
[EXIT_REASON_INVLPG] = handle_invlpg,
|
2011-11-10 12:57:25 +00:00
|
|
|
[EXIT_REASON_RDPMC] = handle_rdpmc,
|
2007-02-19 12:37:47 +00:00
|
|
|
[EXIT_REASON_VMCALL] = handle_vmcall,
|
2011-05-25 20:06:59 +00:00
|
|
|
[EXIT_REASON_VMCLEAR] = handle_vmclear,
|
2011-05-25 20:10:33 +00:00
|
|
|
[EXIT_REASON_VMLAUNCH] = handle_vmlaunch,
|
2011-05-25 20:07:29 +00:00
|
|
|
[EXIT_REASON_VMPTRLD] = handle_vmptrld,
|
2011-05-25 20:08:00 +00:00
|
|
|
[EXIT_REASON_VMPTRST] = handle_vmptrst,
|
2011-05-25 20:08:30 +00:00
|
|
|
[EXIT_REASON_VMREAD] = handle_vmread,
|
2011-05-25 20:10:33 +00:00
|
|
|
[EXIT_REASON_VMRESUME] = handle_vmresume,
|
2011-05-25 20:08:30 +00:00
|
|
|
[EXIT_REASON_VMWRITE] = handle_vmwrite,
|
2011-05-25 20:02:54 +00:00
|
|
|
[EXIT_REASON_VMOFF] = handle_vmoff,
|
|
|
|
[EXIT_REASON_VMON] = handle_vmon,
|
2007-10-29 01:40:42 +00:00
|
|
|
[EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold,
|
|
|
|
[EXIT_REASON_APIC_ACCESS] = handle_apic_access,
|
2013-01-25 02:18:49 +00:00
|
|
|
[EXIT_REASON_APIC_WRITE] = handle_apic_write,
|
2013-01-25 02:18:51 +00:00
|
|
|
[EXIT_REASON_EOI_INDUCED] = handle_apic_eoi_induced,
|
2007-11-11 10:28:35 +00:00
|
|
|
[EXIT_REASON_WBINVD] = handle_wbinvd,
|
2010-06-10 03:27:12 +00:00
|
|
|
[EXIT_REASON_XSETBV] = handle_xsetbv,
|
2008-03-24 21:14:53 +00:00
|
|
|
[EXIT_REASON_TASK_SWITCH] = handle_task_switch,
|
2009-06-08 09:37:09 +00:00
|
|
|
[EXIT_REASON_MCE_DURING_VMENTRY] = handle_machine_check,
|
2009-06-11 15:07:43 +00:00
|
|
|
[EXIT_REASON_EPT_VIOLATION] = handle_ept_violation,
|
|
|
|
[EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig,
|
2009-10-09 10:03:20 +00:00
|
|
|
[EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause,
|
2014-05-07 20:52:13 +00:00
|
|
|
[EXIT_REASON_MWAIT_INSTRUCTION] = handle_mwait,
|
2015-07-05 17:08:57 +00:00
|
|
|
[EXIT_REASON_MONITOR_TRAP_FLAG] = handle_monitor_trap,
|
2014-05-07 20:52:13 +00:00
|
|
|
[EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor,
|
2013-08-05 08:07:17 +00:00
|
|
|
[EXIT_REASON_INVEPT] = handle_invept,
|
2014-09-23 18:22:30 +00:00
|
|
|
[EXIT_REASON_INVVPID] = handle_invvpid,
|
2014-12-02 11:14:58 +00:00
|
|
|
[EXIT_REASON_XSAVES] = handle_xsaves,
|
|
|
|
[EXIT_REASON_XRSTORS] = handle_xrstors,
|
2015-01-28 02:54:28 +00:00
|
|
|
[EXIT_REASON_PML_FULL] = handle_pml_full,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const int kvm_vmx_max_exit_handlers =
|
2007-06-03 17:35:29 +00:00
|
|
|
ARRAY_SIZE(kvm_vmx_exit_handlers);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2013-02-18 10:21:16 +00:00
|
|
|
static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
unsigned long exit_qualification;
|
|
|
|
gpa_t bitmap, last_bitmap;
|
|
|
|
unsigned int port;
|
|
|
|
int size;
|
|
|
|
u8 b;
|
|
|
|
|
|
|
|
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
|
2013-12-30 20:56:29 +00:00
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING);
|
2013-02-18 10:21:16 +00:00
|
|
|
|
|
|
|
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
|
|
|
|
port = exit_qualification >> 16;
|
|
|
|
size = (exit_qualification & 7) + 1;
|
|
|
|
|
|
|
|
last_bitmap = (gpa_t)-1;
|
|
|
|
b = -1;
|
|
|
|
|
|
|
|
while (size > 0) {
|
|
|
|
if (port < 0x8000)
|
|
|
|
bitmap = vmcs12->io_bitmap_a;
|
|
|
|
else if (port < 0x10000)
|
|
|
|
bitmap = vmcs12->io_bitmap_b;
|
|
|
|
else
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
2013-02-18 10:21:16 +00:00
|
|
|
bitmap += (port & 0x7fff) / 8;
|
|
|
|
|
|
|
|
if (last_bitmap != bitmap)
|
2015-04-08 13:39:23 +00:00
|
|
|
if (kvm_vcpu_read_guest(vcpu, bitmap, &b, 1))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
2013-02-18 10:21:16 +00:00
|
|
|
if (b & (1 << (port & 7)))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
2013-02-18 10:21:16 +00:00
|
|
|
|
|
|
|
port++;
|
|
|
|
size--;
|
|
|
|
last_bitmap = bitmap;
|
|
|
|
}
|
|
|
|
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
2013-02-18 10:21:16 +00:00
|
|
|
}
|
|
|
|
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
/*
|
|
|
|
* Return 1 if we should exit from L2 to L1 to handle an MSR access access,
|
|
|
|
* rather than handle it ourselves in L0. I.e., check whether L1 expressed
|
|
|
|
* disinterest in the current event (read or write a specific MSR) by using an
|
|
|
|
* MSR bitmap. This may be the case even when L0 doesn't use MSR bitmaps.
|
|
|
|
*/
|
|
|
|
static bool nested_vmx_exit_handled_msr(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12, u32 exit_reason)
|
|
|
|
{
|
|
|
|
u32 msr_index = vcpu->arch.regs[VCPU_REGS_RCX];
|
|
|
|
gpa_t bitmap;
|
|
|
|
|
2013-02-11 11:19:28 +00:00
|
|
|
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_MSR_BITMAPS))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The MSR_BITMAP page is divided into four 1024-byte bitmaps,
|
|
|
|
* for the four combinations of read/write and low/high MSR numbers.
|
|
|
|
* First we need to figure out which of the four to use:
|
|
|
|
*/
|
|
|
|
bitmap = vmcs12->msr_bitmap;
|
|
|
|
if (exit_reason == EXIT_REASON_MSR_WRITE)
|
|
|
|
bitmap += 2048;
|
|
|
|
if (msr_index >= 0xc0000000) {
|
|
|
|
msr_index -= 0xc0000000;
|
|
|
|
bitmap += 1024;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Then read the msr_index'th bit from this bitmap: */
|
|
|
|
if (msr_index < 1024*8) {
|
|
|
|
unsigned char b;
|
2015-04-08 13:39:23 +00:00
|
|
|
if (kvm_vcpu_read_guest(vcpu, bitmap + msr_index/8, &b, 1))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
return 1 & (b >> (msr_index & 7));
|
|
|
|
} else
|
2015-03-30 23:46:09 +00:00
|
|
|
return true; /* let L1 handle the wrong parameter */
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return 1 if we should exit from L2 to L1 to handle a CR access exit,
|
|
|
|
* rather than handle it ourselves in L0. I.e., check if L1 wanted to
|
|
|
|
* intercept (via guest_host_mask etc.) the current event.
|
|
|
|
*/
|
|
|
|
static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
int cr = exit_qualification & 15;
|
|
|
|
int reg = (exit_qualification >> 8) & 15;
|
2014-06-18 14:19:25 +00:00
|
|
|
unsigned long val = kvm_register_readl(vcpu, reg);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
|
|
|
|
switch ((exit_qualification >> 4) & 3) {
|
|
|
|
case 0: /* mov to cr */
|
|
|
|
switch (cr) {
|
|
|
|
case 0:
|
|
|
|
if (vmcs12->cr0_guest_host_mask &
|
|
|
|
(val ^ vmcs12->cr0_read_shadow))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if ((vmcs12->cr3_target_count >= 1 &&
|
|
|
|
vmcs12->cr3_target_value0 == val) ||
|
|
|
|
(vmcs12->cr3_target_count >= 2 &&
|
|
|
|
vmcs12->cr3_target_value1 == val) ||
|
|
|
|
(vmcs12->cr3_target_count >= 3 &&
|
|
|
|
vmcs12->cr3_target_value2 == val) ||
|
|
|
|
(vmcs12->cr3_target_count >= 4 &&
|
|
|
|
vmcs12->cr3_target_value3 == val))
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
if (nested_cpu_has(vmcs12, CPU_BASED_CR3_LOAD_EXITING))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (vmcs12->cr4_guest_host_mask &
|
|
|
|
(vmcs12->cr4_read_shadow ^ val))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
if (nested_cpu_has(vmcs12, CPU_BASED_CR8_LOAD_EXITING))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2: /* clts */
|
|
|
|
if ((vmcs12->cr0_guest_host_mask & X86_CR0_TS) &&
|
|
|
|
(vmcs12->cr0_read_shadow & X86_CR0_TS))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
case 1: /* mov from cr */
|
|
|
|
switch (cr) {
|
|
|
|
case 3:
|
|
|
|
if (vmcs12->cpu_based_vm_exec_control &
|
|
|
|
CPU_BASED_CR3_STORE_EXITING)
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
if (vmcs12->cpu_based_vm_exec_control &
|
|
|
|
CPU_BASED_CR8_STORE_EXITING)
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3: /* lmsw */
|
|
|
|
/*
|
|
|
|
* lmsw can change bits 1..3 of cr0, and only set bit 0 of
|
|
|
|
* cr0. Other attempted changes are ignored, with no exit.
|
|
|
|
*/
|
|
|
|
if (vmcs12->cr0_guest_host_mask & 0xe &
|
|
|
|
(val ^ vmcs12->cr0_read_shadow))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
if ((vmcs12->cr0_guest_host_mask & 0x1) &&
|
|
|
|
!(vmcs12->cr0_read_shadow & 0x1) &&
|
|
|
|
(val & 0x1))
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return 1 if we should exit from L2 to L1 to handle an exit, or 0 if we
|
|
|
|
* should handle it ourselves in L0 (and then continue L2). Only call this
|
|
|
|
* when in is_guest_mode (L2).
|
|
|
|
*/
|
|
|
|
static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u32 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
2013-02-24 13:11:34 +00:00
|
|
|
u32 exit_reason = vmx->exit_reason;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
|
2014-01-04 17:47:21 +00:00
|
|
|
trace_kvm_nested_vmexit(kvm_rip_read(vcpu), exit_reason,
|
|
|
|
vmcs_readl(EXIT_QUALIFICATION),
|
|
|
|
vmx->idt_vectoring_info,
|
|
|
|
intr_info,
|
|
|
|
vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
|
|
|
|
KVM_ISA_VMX);
|
|
|
|
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
if (vmx->nested.nested_run_pending)
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
|
|
|
|
if (unlikely(vmx->fail)) {
|
2011-09-12 09:26:22 +00:00
|
|
|
pr_info_ratelimited("%s failed vm entry %x\n", __func__,
|
|
|
|
vmcs_read32(VM_INSTRUCTION_ERROR));
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (exit_reason) {
|
|
|
|
case EXIT_REASON_EXCEPTION_NMI:
|
|
|
|
if (!is_exception(intr_info))
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
else if (is_page_fault(intr_info))
|
|
|
|
return enable_ept;
|
2013-11-13 10:45:37 +00:00
|
|
|
else if (is_no_device(intr_info) &&
|
2014-02-27 21:54:11 +00:00
|
|
|
!(vmcs12->guest_cr0 & X86_CR0_TS))
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
return vmcs12->exception_bitmap &
|
|
|
|
(1u << (intr_info & INTR_INFO_VECTOR_MASK));
|
|
|
|
case EXIT_REASON_EXTERNAL_INTERRUPT:
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_TRIPLE_FAULT:
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_PENDING_INTERRUPT:
|
2013-04-14 10:12:45 +00:00
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_VIRTUAL_INTR_PENDING);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_NMI_WINDOW:
|
2013-04-14 10:12:45 +00:00
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_VIRTUAL_NMI_PENDING);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_TASK_SWITCH:
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_CPUID:
|
2014-09-18 21:24:57 +00:00
|
|
|
if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa)
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_HLT:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING);
|
|
|
|
case EXIT_REASON_INVD:
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_INVLPG:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_INVLPG_EXITING);
|
|
|
|
case EXIT_REASON_RDPMC:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_RDPMC_EXITING);
|
2015-03-23 18:27:19 +00:00
|
|
|
case EXIT_REASON_RDTSC: case EXIT_REASON_RDTSCP:
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_RDTSC_EXITING);
|
|
|
|
case EXIT_REASON_VMCALL: case EXIT_REASON_VMCLEAR:
|
|
|
|
case EXIT_REASON_VMLAUNCH: case EXIT_REASON_VMPTRLD:
|
|
|
|
case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD:
|
|
|
|
case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE:
|
|
|
|
case EXIT_REASON_VMOFF: case EXIT_REASON_VMON:
|
2014-09-23 18:22:30 +00:00
|
|
|
case EXIT_REASON_INVEPT: case EXIT_REASON_INVVPID:
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
/*
|
|
|
|
* VMX instructions trap unconditionally. This allows L1 to
|
|
|
|
* emulate them for its L2 guest, i.e., allows 3-level nesting!
|
|
|
|
*/
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_CR_ACCESS:
|
|
|
|
return nested_vmx_exit_handled_cr(vcpu, vmcs12);
|
|
|
|
case EXIT_REASON_DR_ACCESS:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_MOV_DR_EXITING);
|
|
|
|
case EXIT_REASON_IO_INSTRUCTION:
|
2013-02-18 10:21:16 +00:00
|
|
|
return nested_vmx_exit_handled_io(vcpu, vmcs12);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_MSR_READ:
|
|
|
|
case EXIT_REASON_MSR_WRITE:
|
|
|
|
return nested_vmx_exit_handled_msr(vcpu, vmcs12, exit_reason);
|
|
|
|
case EXIT_REASON_INVALID_STATE:
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_MWAIT_INSTRUCTION:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_MWAIT_EXITING);
|
2015-07-05 17:08:57 +00:00
|
|
|
case EXIT_REASON_MONITOR_TRAP_FLAG:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_MONITOR_TRAP_FLAG);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_MONITOR_INSTRUCTION:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_MONITOR_EXITING);
|
|
|
|
case EXIT_REASON_PAUSE_INSTRUCTION:
|
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_PAUSE_EXITING) ||
|
|
|
|
nested_cpu_has2(vmcs12,
|
|
|
|
SECONDARY_EXEC_PAUSE_LOOP_EXITING);
|
|
|
|
case EXIT_REASON_MCE_DURING_VMENTRY:
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_TPR_BELOW_THRESHOLD:
|
2014-08-21 11:46:50 +00:00
|
|
|
return nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_APIC_ACCESS:
|
|
|
|
return nested_cpu_has2(vmcs12,
|
|
|
|
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES);
|
2015-02-03 15:57:18 +00:00
|
|
|
case EXIT_REASON_APIC_WRITE:
|
2015-02-03 15:57:51 +00:00
|
|
|
case EXIT_REASON_EOI_INDUCED:
|
|
|
|
/* apic_write and eoi_induced should exit unconditionally. */
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_EPT_VIOLATION:
|
2013-08-05 08:07:19 +00:00
|
|
|
/*
|
|
|
|
* L0 always deals with the EPT violation. If nested EPT is
|
|
|
|
* used, and the nested mmu code discovers that the address is
|
|
|
|
* missing in the guest EPT table (EPT12), the EPT violation
|
|
|
|
* will be injected with nested_ept_inject_page_fault()
|
|
|
|
*/
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_EPT_MISCONFIG:
|
2013-08-05 08:07:19 +00:00
|
|
|
/*
|
|
|
|
* L2 never uses directly L1's EPT, but rather L0's own EPT
|
|
|
|
* table (shadow on EPT) or a merged EPT table that L0 built
|
|
|
|
* (EPT on EPT). So any problems with the structure of the
|
|
|
|
* table is L0's fault.
|
|
|
|
*/
|
2015-03-30 23:46:09 +00:00
|
|
|
return false;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
case EXIT_REASON_WBINVD:
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING);
|
|
|
|
case EXIT_REASON_XSETBV:
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
2014-12-04 11:11:07 +00:00
|
|
|
case EXIT_REASON_XSAVES: case EXIT_REASON_XRSTORS:
|
|
|
|
/*
|
|
|
|
* This should never happen, since it is not possible to
|
|
|
|
* set XSS to a non-zero value---neither in L1 nor in L2.
|
|
|
|
* If if it were, XSS would have to be checked against
|
|
|
|
* the XSS exit bitmap in vmcs12.
|
|
|
|
*/
|
|
|
|
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES);
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
default:
|
2015-03-30 23:46:09 +00:00
|
|
|
return true;
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-18 11:09:54 +00:00
|
|
|
static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
|
|
|
|
{
|
|
|
|
*info1 = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
*info2 = vmcs_read32(VM_EXIT_INTR_INFO);
|
|
|
|
}
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
static int vmx_enable_pml(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
struct page *pml_pg;
|
|
|
|
u32 exec_control;
|
|
|
|
|
|
|
|
pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
|
|
|
if (!pml_pg)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
vmx->pml_pg = pml_pg;
|
|
|
|
|
|
|
|
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
|
|
|
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
|
|
|
|
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
exec_control |= SECONDARY_EXEC_ENABLE_PML;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_disable_pml(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
u32 exec_control;
|
|
|
|
|
|
|
|
ASSERT(vmx->pml_pg);
|
|
|
|
__free_page(vmx->pml_pg);
|
|
|
|
vmx->pml_pg = NULL;
|
|
|
|
|
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
|
|
|
|
}
|
|
|
|
|
2015-04-08 13:39:23 +00:00
|
|
|
static void vmx_flush_pml_buffer(struct kvm_vcpu *vcpu)
|
2015-01-28 02:54:28 +00:00
|
|
|
{
|
2015-04-08 13:39:23 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2015-01-28 02:54:28 +00:00
|
|
|
u64 *pml_buf;
|
|
|
|
u16 pml_idx;
|
|
|
|
|
|
|
|
pml_idx = vmcs_read16(GUEST_PML_INDEX);
|
|
|
|
|
|
|
|
/* Do nothing if PML buffer is empty */
|
|
|
|
if (pml_idx == (PML_ENTITY_NUM - 1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* PML index always points to next available PML buffer entity */
|
|
|
|
if (pml_idx >= PML_ENTITY_NUM)
|
|
|
|
pml_idx = 0;
|
|
|
|
else
|
|
|
|
pml_idx++;
|
|
|
|
|
|
|
|
pml_buf = page_address(vmx->pml_pg);
|
|
|
|
for (; pml_idx < PML_ENTITY_NUM; pml_idx++) {
|
|
|
|
u64 gpa;
|
|
|
|
|
|
|
|
gpa = pml_buf[pml_idx];
|
|
|
|
WARN_ON(gpa & (PAGE_SIZE - 1));
|
2015-04-08 13:39:23 +00:00
|
|
|
kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
|
2015-01-28 02:54:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* reset PML index */
|
|
|
|
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Flush all vcpus' PML buffer and update logged GPAs to dirty_bitmap.
|
|
|
|
* Called before reporting dirty_bitmap to userspace.
|
|
|
|
*/
|
|
|
|
static void kvm_flush_pml_buffers(struct kvm *kvm)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct kvm_vcpu *vcpu;
|
|
|
|
/*
|
|
|
|
* We only need to kick vcpu out of guest mode here, as PML buffer
|
|
|
|
* is flushed at beginning of all VMEXITs, and it's obvious that only
|
|
|
|
* vcpus running in guest are possible to have unflushed GPAs in PML
|
|
|
|
* buffer.
|
|
|
|
*/
|
|
|
|
kvm_for_each_vcpu(i, vcpu, kvm)
|
|
|
|
kvm_vcpu_kick(vcpu);
|
|
|
|
}
|
|
|
|
|
2015-04-30 10:57:28 +00:00
|
|
|
static void vmx_dump_sel(char *name, uint32_t sel)
|
|
|
|
{
|
|
|
|
pr_err("%s sel=0x%04x, attr=0x%05x, limit=0x%08x, base=0x%016lx\n",
|
|
|
|
name, vmcs_read32(sel),
|
|
|
|
vmcs_read32(sel + GUEST_ES_AR_BYTES - GUEST_ES_SELECTOR),
|
|
|
|
vmcs_read32(sel + GUEST_ES_LIMIT - GUEST_ES_SELECTOR),
|
|
|
|
vmcs_readl(sel + GUEST_ES_BASE - GUEST_ES_SELECTOR));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_dump_dtsel(char *name, uint32_t limit)
|
|
|
|
{
|
|
|
|
pr_err("%s limit=0x%08x, base=0x%016lx\n",
|
|
|
|
name, vmcs_read32(limit),
|
|
|
|
vmcs_readl(limit + GUEST_GDTR_BASE - GUEST_GDTR_LIMIT));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dump_vmcs(void)
|
|
|
|
{
|
|
|
|
u32 vmentry_ctl = vmcs_read32(VM_ENTRY_CONTROLS);
|
|
|
|
u32 vmexit_ctl = vmcs_read32(VM_EXIT_CONTROLS);
|
|
|
|
u32 cpu_based_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
|
|
|
u32 pin_based_exec_ctrl = vmcs_read32(PIN_BASED_VM_EXEC_CONTROL);
|
|
|
|
u32 secondary_exec_control = 0;
|
|
|
|
unsigned long cr4 = vmcs_readl(GUEST_CR4);
|
|
|
|
u64 efer = vmcs_readl(GUEST_IA32_EFER);
|
|
|
|
int i, n;
|
|
|
|
|
|
|
|
if (cpu_has_secondary_exec_ctrls())
|
|
|
|
secondary_exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
|
|
|
|
pr_err("*** Guest State ***\n");
|
|
|
|
pr_err("CR0: actual=0x%016lx, shadow=0x%016lx, gh_mask=%016lx\n",
|
|
|
|
vmcs_readl(GUEST_CR0), vmcs_readl(CR0_READ_SHADOW),
|
|
|
|
vmcs_readl(CR0_GUEST_HOST_MASK));
|
|
|
|
pr_err("CR4: actual=0x%016lx, shadow=0x%016lx, gh_mask=%016lx\n",
|
|
|
|
cr4, vmcs_readl(CR4_READ_SHADOW), vmcs_readl(CR4_GUEST_HOST_MASK));
|
|
|
|
pr_err("CR3 = 0x%016lx\n", vmcs_readl(GUEST_CR3));
|
|
|
|
if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) &&
|
|
|
|
(cr4 & X86_CR4_PAE) && !(efer & EFER_LMA))
|
|
|
|
{
|
|
|
|
pr_err("PDPTR0 = 0x%016lx PDPTR1 = 0x%016lx\n",
|
|
|
|
vmcs_readl(GUEST_PDPTR0), vmcs_readl(GUEST_PDPTR1));
|
|
|
|
pr_err("PDPTR2 = 0x%016lx PDPTR3 = 0x%016lx\n",
|
|
|
|
vmcs_readl(GUEST_PDPTR2), vmcs_readl(GUEST_PDPTR3));
|
|
|
|
}
|
|
|
|
pr_err("RSP = 0x%016lx RIP = 0x%016lx\n",
|
|
|
|
vmcs_readl(GUEST_RSP), vmcs_readl(GUEST_RIP));
|
|
|
|
pr_err("RFLAGS=0x%08lx DR7 = 0x%016lx\n",
|
|
|
|
vmcs_readl(GUEST_RFLAGS), vmcs_readl(GUEST_DR7));
|
|
|
|
pr_err("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
|
|
|
|
vmcs_readl(GUEST_SYSENTER_ESP),
|
|
|
|
vmcs_read32(GUEST_SYSENTER_CS), vmcs_readl(GUEST_SYSENTER_EIP));
|
|
|
|
vmx_dump_sel("CS: ", GUEST_CS_SELECTOR);
|
|
|
|
vmx_dump_sel("DS: ", GUEST_DS_SELECTOR);
|
|
|
|
vmx_dump_sel("SS: ", GUEST_SS_SELECTOR);
|
|
|
|
vmx_dump_sel("ES: ", GUEST_ES_SELECTOR);
|
|
|
|
vmx_dump_sel("FS: ", GUEST_FS_SELECTOR);
|
|
|
|
vmx_dump_sel("GS: ", GUEST_GS_SELECTOR);
|
|
|
|
vmx_dump_dtsel("GDTR:", GUEST_GDTR_LIMIT);
|
|
|
|
vmx_dump_sel("LDTR:", GUEST_LDTR_SELECTOR);
|
|
|
|
vmx_dump_dtsel("IDTR:", GUEST_IDTR_LIMIT);
|
|
|
|
vmx_dump_sel("TR: ", GUEST_TR_SELECTOR);
|
|
|
|
if ((vmexit_ctl & (VM_EXIT_SAVE_IA32_PAT | VM_EXIT_SAVE_IA32_EFER)) ||
|
|
|
|
(vmentry_ctl & (VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_IA32_EFER)))
|
|
|
|
pr_err("EFER = 0x%016llx PAT = 0x%016lx\n",
|
|
|
|
efer, vmcs_readl(GUEST_IA32_PAT));
|
|
|
|
pr_err("DebugCtl = 0x%016lx DebugExceptions = 0x%016lx\n",
|
|
|
|
vmcs_readl(GUEST_IA32_DEBUGCTL),
|
|
|
|
vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS));
|
|
|
|
if (vmentry_ctl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
|
|
|
|
pr_err("PerfGlobCtl = 0x%016lx\n",
|
|
|
|
vmcs_readl(GUEST_IA32_PERF_GLOBAL_CTRL));
|
|
|
|
if (vmentry_ctl & VM_ENTRY_LOAD_BNDCFGS)
|
|
|
|
pr_err("BndCfgS = 0x%016lx\n", vmcs_readl(GUEST_BNDCFGS));
|
|
|
|
pr_err("Interruptibility = %08x ActivityState = %08x\n",
|
|
|
|
vmcs_read32(GUEST_INTERRUPTIBILITY_INFO),
|
|
|
|
vmcs_read32(GUEST_ACTIVITY_STATE));
|
|
|
|
if (secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)
|
|
|
|
pr_err("InterruptStatus = %04x\n",
|
|
|
|
vmcs_read16(GUEST_INTR_STATUS));
|
|
|
|
|
|
|
|
pr_err("*** Host State ***\n");
|
|
|
|
pr_err("RIP = 0x%016lx RSP = 0x%016lx\n",
|
|
|
|
vmcs_readl(HOST_RIP), vmcs_readl(HOST_RSP));
|
|
|
|
pr_err("CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x TR=%04x\n",
|
|
|
|
vmcs_read16(HOST_CS_SELECTOR), vmcs_read16(HOST_SS_SELECTOR),
|
|
|
|
vmcs_read16(HOST_DS_SELECTOR), vmcs_read16(HOST_ES_SELECTOR),
|
|
|
|
vmcs_read16(HOST_FS_SELECTOR), vmcs_read16(HOST_GS_SELECTOR),
|
|
|
|
vmcs_read16(HOST_TR_SELECTOR));
|
|
|
|
pr_err("FSBase=%016lx GSBase=%016lx TRBase=%016lx\n",
|
|
|
|
vmcs_readl(HOST_FS_BASE), vmcs_readl(HOST_GS_BASE),
|
|
|
|
vmcs_readl(HOST_TR_BASE));
|
|
|
|
pr_err("GDTBase=%016lx IDTBase=%016lx\n",
|
|
|
|
vmcs_readl(HOST_GDTR_BASE), vmcs_readl(HOST_IDTR_BASE));
|
|
|
|
pr_err("CR0=%016lx CR3=%016lx CR4=%016lx\n",
|
|
|
|
vmcs_readl(HOST_CR0), vmcs_readl(HOST_CR3),
|
|
|
|
vmcs_readl(HOST_CR4));
|
|
|
|
pr_err("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
|
|
|
|
vmcs_readl(HOST_IA32_SYSENTER_ESP),
|
|
|
|
vmcs_read32(HOST_IA32_SYSENTER_CS),
|
|
|
|
vmcs_readl(HOST_IA32_SYSENTER_EIP));
|
|
|
|
if (vmexit_ctl & (VM_EXIT_LOAD_IA32_PAT | VM_EXIT_LOAD_IA32_EFER))
|
|
|
|
pr_err("EFER = 0x%016lx PAT = 0x%016lx\n",
|
|
|
|
vmcs_readl(HOST_IA32_EFER), vmcs_readl(HOST_IA32_PAT));
|
|
|
|
if (vmexit_ctl & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
|
|
|
|
pr_err("PerfGlobCtl = 0x%016lx\n",
|
|
|
|
vmcs_readl(HOST_IA32_PERF_GLOBAL_CTRL));
|
|
|
|
|
|
|
|
pr_err("*** Control State ***\n");
|
|
|
|
pr_err("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
|
|
|
|
pin_based_exec_ctrl, cpu_based_exec_ctrl, secondary_exec_control);
|
|
|
|
pr_err("EntryControls=%08x ExitControls=%08x\n", vmentry_ctl, vmexit_ctl);
|
|
|
|
pr_err("ExceptionBitmap=%08x PFECmask=%08x PFECmatch=%08x\n",
|
|
|
|
vmcs_read32(EXCEPTION_BITMAP),
|
|
|
|
vmcs_read32(PAGE_FAULT_ERROR_CODE_MASK),
|
|
|
|
vmcs_read32(PAGE_FAULT_ERROR_CODE_MATCH));
|
|
|
|
pr_err("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
|
|
|
|
vmcs_read32(VM_ENTRY_INTR_INFO_FIELD),
|
|
|
|
vmcs_read32(VM_ENTRY_EXCEPTION_ERROR_CODE),
|
|
|
|
vmcs_read32(VM_ENTRY_INSTRUCTION_LEN));
|
|
|
|
pr_err("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n",
|
|
|
|
vmcs_read32(VM_EXIT_INTR_INFO),
|
|
|
|
vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
|
|
|
|
vmcs_read32(VM_EXIT_INSTRUCTION_LEN));
|
|
|
|
pr_err(" reason=%08x qualification=%016lx\n",
|
|
|
|
vmcs_read32(VM_EXIT_REASON), vmcs_readl(EXIT_QUALIFICATION));
|
|
|
|
pr_err("IDTVectoring: info=%08x errcode=%08x\n",
|
|
|
|
vmcs_read32(IDT_VECTORING_INFO_FIELD),
|
|
|
|
vmcs_read32(IDT_VECTORING_ERROR_CODE));
|
|
|
|
pr_err("TSC Offset = 0x%016lx\n", vmcs_readl(TSC_OFFSET));
|
|
|
|
if (cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW)
|
|
|
|
pr_err("TPR Threshold = 0x%02x\n", vmcs_read32(TPR_THRESHOLD));
|
|
|
|
if (pin_based_exec_ctrl & PIN_BASED_POSTED_INTR)
|
|
|
|
pr_err("PostedIntrVec = 0x%02x\n", vmcs_read16(POSTED_INTR_NV));
|
|
|
|
if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT))
|
|
|
|
pr_err("EPT pointer = 0x%016lx\n", vmcs_readl(EPT_POINTER));
|
|
|
|
n = vmcs_read32(CR3_TARGET_COUNT);
|
|
|
|
for (i = 0; i + 1 < n; i += 4)
|
|
|
|
pr_err("CR3 target%u=%016lx target%u=%016lx\n",
|
|
|
|
i, vmcs_readl(CR3_TARGET_VALUE0 + i * 2),
|
|
|
|
i + 1, vmcs_readl(CR3_TARGET_VALUE0 + i * 2 + 2));
|
|
|
|
if (i < n)
|
|
|
|
pr_err("CR3 target%u=%016lx\n",
|
|
|
|
i, vmcs_readl(CR3_TARGET_VALUE0 + i * 2));
|
|
|
|
if (secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
|
|
|
|
pr_err("PLE Gap=%08x Window=%08x\n",
|
|
|
|
vmcs_read32(PLE_GAP), vmcs_read32(PLE_WINDOW));
|
|
|
|
if (secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
|
|
|
|
pr_err("Virtual processor ID = 0x%04x\n",
|
|
|
|
vmcs_read16(VIRTUAL_PROCESSOR_ID));
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/*
|
|
|
|
* The guest has exited. See if we can fix it or if we need userspace
|
|
|
|
* assistance.
|
|
|
|
*/
|
2009-08-24 08:10:17 +00:00
|
|
|
static int vmx_handle_exit(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-09-10 14:27:03 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2009-06-08 09:37:09 +00:00
|
|
|
u32 exit_reason = vmx->exit_reason;
|
2007-11-22 09:30:47 +00:00
|
|
|
u32 vectoring_info = vmx->idt_vectoring_info;
|
2007-09-10 14:27:03 +00:00
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
/*
|
|
|
|
* Flush logged GPAs PML buffer, this will make dirty_bitmap more
|
|
|
|
* updated. Another good is, in kvm_vm_ioctl_get_dirty_log, before
|
|
|
|
* querying dirty_bitmap, we only need to kick all vcpus out of guest
|
|
|
|
* mode as if vcpus is in root mode, the PML buffer must has been
|
|
|
|
* flushed already.
|
|
|
|
*/
|
|
|
|
if (enable_pml)
|
2015-04-08 13:39:23 +00:00
|
|
|
vmx_flush_pml_buffer(vcpu);
|
2015-01-28 02:54:28 +00:00
|
|
|
|
2009-09-01 10:48:18 +00:00
|
|
|
/* If guest state is invalid, start emulating */
|
2013-01-21 13:36:49 +00:00
|
|
|
if (vmx->emulation_required)
|
2009-09-01 10:48:18 +00:00
|
|
|
return handle_invalid_guest_state(vcpu);
|
2008-10-29 08:39:42 +00:00
|
|
|
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
if (is_guest_mode(vcpu) && nested_vmx_exit_handled(vcpu)) {
|
2014-01-04 17:47:20 +00:00
|
|
|
nested_vmx_vmexit(vcpu, exit_reason,
|
|
|
|
vmcs_read32(VM_EXIT_INTR_INFO),
|
|
|
|
vmcs_readl(EXIT_QUALIFICATION));
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-05-31 19:40:54 +00:00
|
|
|
if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
|
2015-04-30 10:57:28 +00:00
|
|
|
dump_vmcs();
|
2010-05-31 19:40:54 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
|
|
|
|
vcpu->run->fail_entry.hardware_entry_failure_reason
|
|
|
|
= exit_reason;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-10 14:27:03 +00:00
|
|
|
if (unlikely(vmx->fail)) {
|
2009-08-24 08:10:17 +00:00
|
|
|
vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
|
|
|
|
vcpu->run->fail_entry.hardware_entry_failure_reason
|
2007-09-10 14:27:03 +00:00
|
|
|
= vmcs_read32(VM_INSTRUCTION_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2012-10-17 05:46:52 +00:00
|
|
|
/*
|
|
|
|
* Note:
|
|
|
|
* Do not try to fix EXIT_REASON_EPT_MISCONFIG if it caused by
|
|
|
|
* delivery event since it indicates guest is accessing MMIO.
|
|
|
|
* The vm-exit can be triggered again after return to guest that
|
|
|
|
* will cause infinite loop.
|
|
|
|
*/
|
2007-10-08 13:02:08 +00:00
|
|
|
if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
|
2008-04-28 04:24:45 +00:00
|
|
|
(exit_reason != EXIT_REASON_EXCEPTION_NMI &&
|
2008-09-26 07:30:47 +00:00
|
|
|
exit_reason != EXIT_REASON_EPT_VIOLATION &&
|
2012-10-17 05:46:52 +00:00
|
|
|
exit_reason != EXIT_REASON_TASK_SWITCH)) {
|
|
|
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
|
|
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
|
|
|
vcpu->run->internal.ndata = 2;
|
|
|
|
vcpu->run->internal.data[0] = vectoring_info;
|
|
|
|
vcpu->run->internal.data[1] = exit_reason;
|
|
|
|
return 0;
|
|
|
|
}
|
2008-09-26 07:30:57 +00:00
|
|
|
|
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
This patch contains the logic of whether an L2 exit should be handled by L0
and then L2 should be resumed, or whether L1 should be run to handle this
exit (using the nested_vmx_vmexit() function of the previous patch).
The basic idea is to let L1 handle the exit only if it actually asked to
trap this sort of event. For example, when L2 exits on a change to CR0,
we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
bit which changed; If it did, we exit to L1. But if it didn't it means that
it is we (L0) that wished to trap this event, so we handle it ourselves.
The next two patches add additional logic of what to do when an interrupt or
exception is injected: Does L0 need to do it, should we exit to L1 to do it,
or should we resume L2 and keep the exception to be injected later.
We keep a new flag, "nested_run_pending", which can override the decision of
which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
and therefore expects L2 to be run (and perhaps be injected with an event it
specified, etc.). Nested_run_pending is especially intended to avoid switching
to L1 in the injection decision-point described above.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2011-05-25 20:12:35 +00:00
|
|
|
if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked &&
|
|
|
|
!(is_guest_mode(vcpu) && nested_cpu_has_virtual_nmis(
|
2013-08-05 08:07:20 +00:00
|
|
|
get_vmcs12(vcpu))))) {
|
2009-04-21 14:45:07 +00:00
|
|
|
if (vmx_interrupt_allowed(vcpu)) {
|
2008-09-26 07:30:57 +00:00
|
|
|
vmx->soft_vnmi_blocked = 0;
|
|
|
|
} else if (vmx->vnmi_blocked_time > 1000000000LL &&
|
2008-12-11 15:54:54 +00:00
|
|
|
vcpu->arch.nmi_pending) {
|
2008-09-26 07:30:57 +00:00
|
|
|
/*
|
|
|
|
* This CPU don't support us in finding the end of an
|
|
|
|
* NMI-blocked window if the guest runs with IRQs
|
|
|
|
* disabled. So we pull the trigger after 1 s of
|
|
|
|
* futile waiting, but inform the user about this.
|
|
|
|
*/
|
|
|
|
printk(KERN_WARNING "%s: Breaking out of NMI-blocked "
|
|
|
|
"state on VCPU %d after 1 s timeout\n",
|
|
|
|
__func__, vcpu->vcpu_id);
|
|
|
|
vmx->soft_vnmi_blocked = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
if (exit_reason < kvm_vmx_max_exit_handlers
|
|
|
|
&& kvm_vmx_exit_handlers[exit_reason])
|
2009-08-24 08:10:17 +00:00
|
|
|
return kvm_vmx_exit_handlers[exit_reason](vcpu);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
else {
|
2014-09-18 13:21:16 +00:00
|
|
|
WARN_ONCE(1, "vmx: unexpected exit reason 0x%x\n", exit_reason);
|
|
|
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
|
|
return 1;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-21 14:45:08 +00:00
|
|
|
static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
|
2007-09-12 10:03:11 +00:00
|
|
|
{
|
2014-08-21 11:46:50 +00:00
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
|
|
|
|
if (is_guest_mode(vcpu) &&
|
|
|
|
nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW))
|
|
|
|
return;
|
|
|
|
|
2009-04-21 14:45:08 +00:00
|
|
|
if (irr == -1 || tpr < irr) {
|
2007-09-12 10:03:11 +00:00
|
|
|
vmcs_write32(TPR_THRESHOLD, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-04-21 14:45:08 +00:00
|
|
|
vmcs_write32(TPR_THRESHOLD, irr);
|
2007-09-12 10:03:11 +00:00
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:50 +00:00
|
|
|
static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
|
|
|
|
{
|
|
|
|
u32 sec_exec_control;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* There is not point to enable virtualize x2apic without enable
|
|
|
|
* apicv
|
|
|
|
*/
|
2013-01-25 02:18:51 +00:00
|
|
|
if (!cpu_has_vmx_virtualize_x2apic_mode() ||
|
2015-07-29 10:05:37 +00:00
|
|
|
!vmx_cpu_uses_apicv(vcpu))
|
2013-01-25 02:18:50 +00:00
|
|
|
return;
|
|
|
|
|
2015-07-29 10:05:37 +00:00
|
|
|
if (!cpu_need_tpr_shadow(vcpu))
|
2013-01-25 02:18:50 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
sec_exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
|
|
|
|
if (set) {
|
|
|
|
sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
|
|
sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
|
|
} else {
|
|
|
|
sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
|
|
sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
|
|
}
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control);
|
|
|
|
|
|
|
|
vmx_set_msr_bitmap(vcpu);
|
|
|
|
}
|
|
|
|
|
2014-09-24 07:57:54 +00:00
|
|
|
static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Currently we do not handle the nested case where L2 has an
|
|
|
|
* APIC access page of its own; that page is still pinned.
|
|
|
|
* Hence, we skip the case where the VCPU is in guest mode _and_
|
|
|
|
* L1 prepared an APIC access page for L2.
|
|
|
|
*
|
|
|
|
* For the case where L1 and L2 share the same APIC access page
|
|
|
|
* (flexpriority=Y but SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES clear
|
|
|
|
* in the vmcs12), this function will only update either the vmcs01
|
|
|
|
* or the vmcs02. If the former, the vmcs02 will be updated by
|
|
|
|
* prepare_vmcs02. If the latter, the vmcs01 will be updated in
|
|
|
|
* the next L2->L1 exit.
|
|
|
|
*/
|
|
|
|
if (!is_guest_mode(vcpu) ||
|
|
|
|
!nested_cpu_has2(vmx->nested.current_vmcs12,
|
|
|
|
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
|
|
|
|
vmcs_write64(APIC_ACCESS_ADDR, hpa);
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:51 +00:00
|
|
|
static void vmx_hwapic_isr_update(struct kvm *kvm, int isr)
|
|
|
|
{
|
|
|
|
u16 status;
|
|
|
|
u8 old;
|
|
|
|
|
|
|
|
if (isr == -1)
|
|
|
|
isr = 0;
|
|
|
|
|
|
|
|
status = vmcs_read16(GUEST_INTR_STATUS);
|
|
|
|
old = status >> 8;
|
|
|
|
if (isr != old) {
|
|
|
|
status &= 0xff;
|
|
|
|
status |= isr << 8;
|
|
|
|
vmcs_write16(GUEST_INTR_STATUS, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_set_rvi(int vector)
|
|
|
|
{
|
|
|
|
u16 status;
|
|
|
|
u8 old;
|
|
|
|
|
2014-11-05 02:53:43 +00:00
|
|
|
if (vector == -1)
|
|
|
|
vector = 0;
|
|
|
|
|
2013-01-25 02:18:51 +00:00
|
|
|
status = vmcs_read16(GUEST_INTR_STATUS);
|
|
|
|
old = (u8)status & 0xff;
|
|
|
|
if ((u8)vector != old) {
|
|
|
|
status &= ~0xff;
|
|
|
|
status |= (u8)vector;
|
|
|
|
vmcs_write16(GUEST_INTR_STATUS, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
|
|
|
|
{
|
2014-11-05 02:53:43 +00:00
|
|
|
if (!is_guest_mode(vcpu)) {
|
|
|
|
vmx_set_rvi(max_irr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-25 02:18:51 +00:00
|
|
|
if (max_irr == -1)
|
|
|
|
return;
|
|
|
|
|
2014-07-17 11:03:00 +00:00
|
|
|
/*
|
2014-11-05 02:53:43 +00:00
|
|
|
* In guest mode. If a vmexit is needed, vmx_check_nested_events
|
|
|
|
* handles it.
|
2014-07-17 11:03:00 +00:00
|
|
|
*/
|
2014-11-05 02:53:43 +00:00
|
|
|
if (nested_exit_on_intr(vcpu))
|
2014-07-17 11:03:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
2014-11-05 02:53:43 +00:00
|
|
|
* Else, fall back to pre-APICv interrupt injection since L2
|
2014-07-17 11:03:00 +00:00
|
|
|
* is run without virtual interrupt delivery.
|
|
|
|
*/
|
|
|
|
if (!kvm_event_needs_reinjection(vcpu) &&
|
|
|
|
vmx_interrupt_allowed(vcpu)) {
|
|
|
|
kvm_queue_interrupt(vcpu, max_irr, false);
|
|
|
|
vmx_inject_irq(vcpu);
|
|
|
|
}
|
2013-01-25 02:18:51 +00:00
|
|
|
}
|
|
|
|
|
2015-07-29 08:43:18 +00:00
|
|
|
static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu)
|
2013-01-25 02:18:51 +00:00
|
|
|
{
|
2015-07-29 08:43:18 +00:00
|
|
|
u64 *eoi_exit_bitmap = vcpu->arch.eoi_exit_bitmap;
|
2015-07-29 10:05:37 +00:00
|
|
|
if (!vmx_cpu_uses_apicv(vcpu))
|
2013-04-11 11:25:13 +00:00
|
|
|
return;
|
|
|
|
|
2013-01-25 02:18:51 +00:00
|
|
|
vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP3, eoi_exit_bitmap[3]);
|
|
|
|
}
|
|
|
|
|
2010-07-20 11:31:20 +00:00
|
|
|
static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx)
|
2008-07-01 13:20:21 +00:00
|
|
|
{
|
2011-03-07 15:24:54 +00:00
|
|
|
u32 exit_intr_info;
|
|
|
|
|
|
|
|
if (!(vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY
|
|
|
|
|| vmx->exit_reason == EXIT_REASON_EXCEPTION_NMI))
|
|
|
|
return;
|
|
|
|
|
2011-03-07 15:37:37 +00:00
|
|
|
vmx->exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
|
2011-03-07 15:24:54 +00:00
|
|
|
exit_intr_info = vmx->exit_intr_info;
|
2009-06-08 09:37:09 +00:00
|
|
|
|
|
|
|
/* Handle machine checks before interrupts are enabled */
|
2011-03-07 15:24:54 +00:00
|
|
|
if (is_machine_check(exit_intr_info))
|
2009-06-08 09:37:09 +00:00
|
|
|
kvm_machine_check();
|
|
|
|
|
2009-05-11 10:35:55 +00:00
|
|
|
/* We need to handle NMIs before interrupts are enabled */
|
2011-03-07 15:24:54 +00:00
|
|
|
if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
|
2010-04-19 05:32:45 +00:00
|
|
|
(exit_intr_info & INTR_INFO_VALID_MASK)) {
|
|
|
|
kvm_before_handle_nmi(&vmx->vcpu);
|
2009-05-11 10:35:55 +00:00
|
|
|
asm("int $2");
|
2010-04-19 05:32:45 +00:00
|
|
|
kvm_after_handle_nmi(&vmx->vcpu);
|
|
|
|
}
|
2010-07-20 11:31:20 +00:00
|
|
|
}
|
2009-05-11 10:35:55 +00:00
|
|
|
|
2013-04-11 11:25:10 +00:00
|
|
|
static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If external interrupt exists, IF bit is set in rflags/eflags on the
|
|
|
|
* interrupt stack frame, and interrupt will be enabled on a return
|
|
|
|
* from interrupt handler.
|
|
|
|
*/
|
|
|
|
if ((exit_intr_info & (INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK))
|
|
|
|
== (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR)) {
|
|
|
|
unsigned int vector;
|
|
|
|
unsigned long entry;
|
|
|
|
gate_desc *desc;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
unsigned long tmp;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
|
|
|
|
desc = (gate_desc *)vmx->host_idt_base + vector;
|
|
|
|
entry = gate_offset(*desc);
|
|
|
|
asm volatile(
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
"mov %%" _ASM_SP ", %[sp]\n\t"
|
|
|
|
"and $0xfffffffffffffff0, %%" _ASM_SP "\n\t"
|
|
|
|
"push $%c[ss]\n\t"
|
|
|
|
"push %[sp]\n\t"
|
|
|
|
#endif
|
|
|
|
"pushf\n\t"
|
|
|
|
"orl $0x200, (%%" _ASM_SP ")\n\t"
|
|
|
|
__ASM_SIZE(push) " $%c[cs]\n\t"
|
|
|
|
"call *%[entry]\n\t"
|
|
|
|
:
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
[sp]"=&r"(tmp)
|
|
|
|
#endif
|
|
|
|
:
|
|
|
|
[entry]"r"(entry),
|
|
|
|
[ss]"i"(__KERNEL_DS),
|
|
|
|
[cs]"i"(__KERNEL_CS)
|
|
|
|
);
|
|
|
|
} else
|
|
|
|
local_irq_enable();
|
|
|
|
}
|
|
|
|
|
2015-04-01 12:25:33 +00:00
|
|
|
static bool vmx_has_high_real_mode_segbase(void)
|
|
|
|
{
|
|
|
|
return enable_unrestricted_guest || emulate_invalid_guest_state;
|
|
|
|
}
|
|
|
|
|
2014-02-24 10:55:46 +00:00
|
|
|
static bool vmx_mpx_supported(void)
|
|
|
|
{
|
|
|
|
return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) &&
|
|
|
|
(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS);
|
|
|
|
}
|
|
|
|
|
2014-12-02 11:21:30 +00:00
|
|
|
static bool vmx_xsaves_supported(void)
|
|
|
|
{
|
|
|
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
|
|
|
SECONDARY_EXEC_XSAVES;
|
|
|
|
}
|
|
|
|
|
2010-07-20 11:31:20 +00:00
|
|
|
static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
|
|
|
|
{
|
2011-03-07 15:37:37 +00:00
|
|
|
u32 exit_intr_info;
|
2010-07-20 11:31:20 +00:00
|
|
|
bool unblock_nmi;
|
|
|
|
u8 vector;
|
|
|
|
bool idtv_info_valid;
|
|
|
|
|
|
|
|
idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
|
2009-05-11 10:35:55 +00:00
|
|
|
|
2008-07-01 13:20:21 +00:00
|
|
|
if (cpu_has_virtual_nmis()) {
|
2011-03-07 14:52:07 +00:00
|
|
|
if (vmx->nmi_known_unmasked)
|
|
|
|
return;
|
2011-03-07 15:37:37 +00:00
|
|
|
/*
|
|
|
|
* Can't use vmx->exit_intr_info since we're not sure what
|
|
|
|
* the exit reason is.
|
|
|
|
*/
|
|
|
|
exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
|
2008-07-01 13:20:21 +00:00
|
|
|
unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0;
|
|
|
|
vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
|
|
|
|
/*
|
2009-03-30 13:03:08 +00:00
|
|
|
* SDM 3: 27.7.1.2 (September 2008)
|
2008-07-01 13:20:21 +00:00
|
|
|
* Re-set bit "block by NMI" before VM entry if vmexit caused by
|
|
|
|
* a guest IRET fault.
|
2009-03-30 13:03:08 +00:00
|
|
|
* SDM 3: 23.2.2 (September 2008)
|
|
|
|
* Bit 12 is undefined in any of the following cases:
|
|
|
|
* If the VM exit sets the valid bit in the IDT-vectoring
|
|
|
|
* information field.
|
|
|
|
* If the VM exit is due to a double fault.
|
2008-07-01 13:20:21 +00:00
|
|
|
*/
|
2009-03-30 13:03:08 +00:00
|
|
|
if ((exit_intr_info & INTR_INFO_VALID_MASK) && unblock_nmi &&
|
|
|
|
vector != DF_VECTOR && !idtv_info_valid)
|
2008-07-01 13:20:21 +00:00
|
|
|
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
|
|
|
|
GUEST_INTR_STATE_NMI);
|
2011-03-07 14:52:07 +00:00
|
|
|
else
|
|
|
|
vmx->nmi_known_unmasked =
|
|
|
|
!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)
|
|
|
|
& GUEST_INTR_STATE_NMI);
|
2008-09-26 07:30:57 +00:00
|
|
|
} else if (unlikely(vmx->soft_vnmi_blocked))
|
|
|
|
vmx->vnmi_blocked_time +=
|
|
|
|
ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
|
2010-07-20 11:31:20 +00:00
|
|
|
}
|
|
|
|
|
2013-02-20 13:03:24 +00:00
|
|
|
static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu,
|
2010-07-20 11:43:23 +00:00
|
|
|
u32 idt_vectoring_info,
|
|
|
|
int instr_len_field,
|
|
|
|
int error_code_field)
|
2010-07-20 11:31:20 +00:00
|
|
|
{
|
|
|
|
u8 vector;
|
|
|
|
int type;
|
|
|
|
bool idtv_info_valid;
|
|
|
|
|
|
|
|
idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
|
2008-07-02 06:28:55 +00:00
|
|
|
|
2013-02-20 13:03:24 +00:00
|
|
|
vcpu->arch.nmi_injected = false;
|
|
|
|
kvm_clear_exception_queue(vcpu);
|
|
|
|
kvm_clear_interrupt_queue(vcpu);
|
2009-03-30 13:03:13 +00:00
|
|
|
|
|
|
|
if (!idtv_info_valid)
|
|
|
|
return;
|
|
|
|
|
2013-02-20 13:03:24 +00:00
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
2010-07-27 09:30:24 +00:00
|
|
|
|
2008-07-02 06:28:55 +00:00
|
|
|
vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
|
|
|
|
type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
|
2009-03-30 13:03:13 +00:00
|
|
|
|
2009-03-30 13:03:29 +00:00
|
|
|
switch (type) {
|
2009-03-30 13:03:13 +00:00
|
|
|
case INTR_TYPE_NMI_INTR:
|
2013-02-20 13:03:24 +00:00
|
|
|
vcpu->arch.nmi_injected = true;
|
2008-07-02 06:28:55 +00:00
|
|
|
/*
|
2009-03-30 13:03:08 +00:00
|
|
|
* SDM 3: 27.7.1.2 (September 2008)
|
2009-03-30 13:03:13 +00:00
|
|
|
* Clear bit "block by NMI" before VM entry if a NMI
|
|
|
|
* delivery faulted.
|
2008-07-02 06:28:55 +00:00
|
|
|
*/
|
2013-02-20 13:03:24 +00:00
|
|
|
vmx_set_nmi_mask(vcpu, false);
|
2009-03-30 13:03:13 +00:00
|
|
|
break;
|
|
|
|
case INTR_TYPE_SOFT_EXCEPTION:
|
2013-02-20 13:03:24 +00:00
|
|
|
vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field);
|
2009-05-11 10:35:50 +00:00
|
|
|
/* fall through */
|
|
|
|
case INTR_TYPE_HARD_EXCEPTION:
|
2008-07-03 11:50:12 +00:00
|
|
|
if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
|
2010-07-20 11:43:23 +00:00
|
|
|
u32 err = vmcs_read32(error_code_field);
|
2013-09-25 09:51:34 +00:00
|
|
|
kvm_requeue_exception_e(vcpu, vector, err);
|
2008-07-03 11:50:12 +00:00
|
|
|
} else
|
2013-09-25 09:51:34 +00:00
|
|
|
kvm_requeue_exception(vcpu, vector);
|
2009-03-30 13:03:13 +00:00
|
|
|
break;
|
2009-05-11 10:35:50 +00:00
|
|
|
case INTR_TYPE_SOFT_INTR:
|
2013-02-20 13:03:24 +00:00
|
|
|
vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field);
|
2009-05-11 10:35:50 +00:00
|
|
|
/* fall through */
|
2009-03-30 13:03:13 +00:00
|
|
|
case INTR_TYPE_EXT_INTR:
|
2013-02-20 13:03:24 +00:00
|
|
|
kvm_queue_interrupt(vcpu, vector, type == INTR_TYPE_SOFT_INTR);
|
2009-03-30 13:03:13 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2008-07-03 13:14:28 +00:00
|
|
|
}
|
2008-07-01 13:20:21 +00:00
|
|
|
}
|
|
|
|
|
2010-07-20 11:43:23 +00:00
|
|
|
static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
|
|
|
|
{
|
2013-02-20 13:03:24 +00:00
|
|
|
__vmx_complete_interrupts(&vmx->vcpu, vmx->idt_vectoring_info,
|
2010-07-20 11:43:23 +00:00
|
|
|
VM_EXIT_INSTRUCTION_LEN,
|
|
|
|
IDT_VECTORING_ERROR_CODE);
|
|
|
|
}
|
|
|
|
|
2010-07-20 12:06:17 +00:00
|
|
|
static void vmx_cancel_injection(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2013-02-20 13:03:24 +00:00
|
|
|
__vmx_complete_interrupts(vcpu,
|
2010-07-20 12:06:17 +00:00
|
|
|
vmcs_read32(VM_ENTRY_INTR_INFO_FIELD),
|
|
|
|
VM_ENTRY_INSTRUCTION_LEN,
|
|
|
|
VM_ENTRY_EXCEPTION_ERROR_CODE);
|
|
|
|
|
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
|
|
|
|
}
|
|
|
|
|
2011-10-05 12:01:23 +00:00
|
|
|
static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
|
|
|
|
{
|
|
|
|
int i, nr_msrs;
|
|
|
|
struct perf_guest_switch_msr *msrs;
|
|
|
|
|
|
|
|
msrs = perf_guest_get_msrs(&nr_msrs);
|
|
|
|
|
|
|
|
if (!msrs)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < nr_msrs; i++)
|
|
|
|
if (msrs[i].host == msrs[i].guest)
|
|
|
|
clear_atomic_switch_msr(vmx, msrs[i].msr);
|
|
|
|
else
|
|
|
|
add_atomic_switch_msr(vmx, msrs[i].msr, msrs[i].guest,
|
|
|
|
msrs[i].host);
|
|
|
|
}
|
|
|
|
|
2011-02-11 06:29:40 +00:00
|
|
|
static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-07-27 12:13:10 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2014-10-08 16:02:13 +00:00
|
|
|
unsigned long debugctlmsr, cr4;
|
2010-11-18 11:12:52 +00:00
|
|
|
|
|
|
|
/* Record the guest's net vcpu time for enforced NMI injections. */
|
|
|
|
if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
|
|
|
|
vmx->entry_time = ktime_get();
|
|
|
|
|
|
|
|
/* Don't enter VMX if guest state is invalid, let the exit handler
|
|
|
|
start emulation until we arrive back to a valid state */
|
2013-01-21 13:36:49 +00:00
|
|
|
if (vmx->emulation_required)
|
2010-11-18 11:12:52 +00:00
|
|
|
return;
|
|
|
|
|
2014-08-21 16:08:07 +00:00
|
|
|
if (vmx->ple_window_dirty) {
|
|
|
|
vmx->ple_window_dirty = false;
|
|
|
|
vmcs_write32(PLE_WINDOW, vmx->ple_window);
|
|
|
|
}
|
|
|
|
|
2013-04-18 11:39:25 +00:00
|
|
|
if (vmx->nested.sync_shadow_vmcs) {
|
|
|
|
copy_vmcs12_to_shadow(vmx);
|
|
|
|
vmx->nested.sync_shadow_vmcs = false;
|
|
|
|
}
|
|
|
|
|
2010-11-18 11:12:52 +00:00
|
|
|
if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty))
|
|
|
|
vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
|
|
|
|
if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
|
|
|
|
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
|
|
|
|
|
2014-10-24 22:58:08 +00:00
|
|
|
cr4 = cr4_read_shadow();
|
2014-10-08 16:02:13 +00:00
|
|
|
if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) {
|
|
|
|
vmcs_writel(HOST_CR4, cr4);
|
|
|
|
vmx->host_state.vmcs_host_cr4 = cr4;
|
|
|
|
}
|
|
|
|
|
2010-11-18 11:12:52 +00:00
|
|
|
/* When single-stepping over STI and MOV SS, we must clear the
|
|
|
|
* corresponding interruptibility bits in the guest state. Otherwise
|
|
|
|
* vmentry fails as it then expects bit 14 (BS) in pending debug
|
|
|
|
* exceptions being set, but that's not correct for the guest debugging
|
|
|
|
* case. */
|
|
|
|
if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
|
|
|
|
vmx_set_interrupt_shadow(vcpu, 0);
|
|
|
|
|
2011-10-05 12:01:23 +00:00
|
|
|
atomic_switch_perf_msrs(vmx);
|
2012-08-12 13:12:29 +00:00
|
|
|
debugctlmsr = get_debugctlmsr();
|
2011-10-05 12:01:23 +00:00
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
vmx->__launched = vmx->loaded_vmcs->launched;
|
2010-11-18 11:12:52 +00:00
|
|
|
asm(
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* Store host registers */
|
2012-09-16 12:10:58 +00:00
|
|
|
"push %%" _ASM_DX "; push %%" _ASM_BP ";"
|
|
|
|
"push %%" _ASM_CX " \n\t" /* placeholder for guest rcx */
|
|
|
|
"push %%" _ASM_CX " \n\t"
|
|
|
|
"cmp %%" _ASM_SP ", %c[host_rsp](%0) \n\t"
|
2008-07-17 15:04:30 +00:00
|
|
|
"je 1f \n\t"
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %%" _ASM_SP ", %c[host_rsp](%0) \n\t"
|
2008-05-13 10:23:38 +00:00
|
|
|
__ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
|
2008-07-17 15:04:30 +00:00
|
|
|
"1: \n\t"
|
2009-06-16 09:33:56 +00:00
|
|
|
/* Reload cr2 if changed */
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %c[cr2](%0), %%" _ASM_AX " \n\t"
|
|
|
|
"mov %%cr2, %%" _ASM_DX " \n\t"
|
|
|
|
"cmp %%" _ASM_AX ", %%" _ASM_DX " \n\t"
|
2009-06-16 09:33:56 +00:00
|
|
|
"je 2f \n\t"
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %%" _ASM_AX", %%cr2 \n\t"
|
2009-06-16 09:33:56 +00:00
|
|
|
"2: \n\t"
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* Check if vmlaunch of vmresume is needed */
|
2007-11-15 16:06:18 +00:00
|
|
|
"cmpl $0, %c[launched](%0) \n\t"
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* Load guest registers. Don't clobber flags. */
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %c[rax](%0), %%" _ASM_AX " \n\t"
|
|
|
|
"mov %c[rbx](%0), %%" _ASM_BX " \n\t"
|
|
|
|
"mov %c[rdx](%0), %%" _ASM_DX " \n\t"
|
|
|
|
"mov %c[rsi](%0), %%" _ASM_SI " \n\t"
|
|
|
|
"mov %c[rdi](%0), %%" _ASM_DI " \n\t"
|
|
|
|
"mov %c[rbp](%0), %%" _ASM_BP " \n\t"
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2007-11-15 16:06:18 +00:00
|
|
|
"mov %c[r8](%0), %%r8 \n\t"
|
|
|
|
"mov %c[r9](%0), %%r9 \n\t"
|
|
|
|
"mov %c[r10](%0), %%r10 \n\t"
|
|
|
|
"mov %c[r11](%0), %%r11 \n\t"
|
|
|
|
"mov %c[r12](%0), %%r12 \n\t"
|
|
|
|
"mov %c[r13](%0), %%r13 \n\t"
|
|
|
|
"mov %c[r14](%0), %%r14 \n\t"
|
|
|
|
"mov %c[r15](%0), %%r15 \n\t"
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#endif
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %c[rcx](%0), %%" _ASM_CX " \n\t" /* kills %0 (ecx) */
|
2008-07-14 11:44:59 +00:00
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* Enter guest mode */
|
2012-09-16 12:10:57 +00:00
|
|
|
"jne 1f \n\t"
|
2008-05-13 10:23:38 +00:00
|
|
|
__ex(ASM_VMX_VMLAUNCH) "\n\t"
|
2012-09-16 12:10:57 +00:00
|
|
|
"jmp 2f \n\t"
|
|
|
|
"1: " __ex(ASM_VMX_VMRESUME) "\n\t"
|
|
|
|
"2: "
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
/* Save guest registers, load host registers, keep flags */
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %0, %c[wordsize](%%" _ASM_SP ") \n\t"
|
2011-01-06 16:09:12 +00:00
|
|
|
"pop %0 \n\t"
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %%" _ASM_AX ", %c[rax](%0) \n\t"
|
|
|
|
"mov %%" _ASM_BX ", %c[rbx](%0) \n\t"
|
|
|
|
__ASM_SIZE(pop) " %c[rcx](%0) \n\t"
|
|
|
|
"mov %%" _ASM_DX ", %c[rdx](%0) \n\t"
|
|
|
|
"mov %%" _ASM_SI ", %c[rsi](%0) \n\t"
|
|
|
|
"mov %%" _ASM_DI ", %c[rdi](%0) \n\t"
|
|
|
|
"mov %%" _ASM_BP ", %c[rbp](%0) \n\t"
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2007-11-15 16:06:18 +00:00
|
|
|
"mov %%r8, %c[r8](%0) \n\t"
|
|
|
|
"mov %%r9, %c[r9](%0) \n\t"
|
|
|
|
"mov %%r10, %c[r10](%0) \n\t"
|
|
|
|
"mov %%r11, %c[r11](%0) \n\t"
|
|
|
|
"mov %%r12, %c[r12](%0) \n\t"
|
|
|
|
"mov %%r13, %c[r13](%0) \n\t"
|
|
|
|
"mov %%r14, %c[r14](%0) \n\t"
|
|
|
|
"mov %%r15, %c[r15](%0) \n\t"
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#endif
|
2012-09-16 12:10:58 +00:00
|
|
|
"mov %%cr2, %%" _ASM_AX " \n\t"
|
|
|
|
"mov %%" _ASM_AX ", %c[cr2](%0) \n\t"
|
2008-07-14 11:44:59 +00:00
|
|
|
|
2012-09-16 12:10:58 +00:00
|
|
|
"pop %%" _ASM_BP "; pop %%" _ASM_DX " \n\t"
|
2007-11-15 16:06:18 +00:00
|
|
|
"setbe %c[fail](%0) \n\t"
|
2012-09-16 12:10:57 +00:00
|
|
|
".pushsection .rodata \n\t"
|
|
|
|
".global vmx_return \n\t"
|
|
|
|
"vmx_return: " _ASM_PTR " 2b \n\t"
|
|
|
|
".popsection"
|
2007-11-15 16:06:18 +00:00
|
|
|
: : "c"(vmx), "d"((unsigned long)HOST_RSP),
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
[launched]"i"(offsetof(struct vcpu_vmx, __launched)),
|
2007-11-15 16:06:18 +00:00
|
|
|
[fail]"i"(offsetof(struct vcpu_vmx, fail)),
|
2008-07-17 15:04:30 +00:00
|
|
|
[host_rsp]"i"(offsetof(struct vcpu_vmx, host_rsp)),
|
2007-12-13 15:50:52 +00:00
|
|
|
[rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])),
|
|
|
|
[rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])),
|
|
|
|
[rcx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RCX])),
|
|
|
|
[rdx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDX])),
|
|
|
|
[rsi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RSI])),
|
|
|
|
[rdi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDI])),
|
|
|
|
[rbp]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBP])),
|
2006-12-13 08:33:45 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
2007-12-13 15:50:52 +00:00
|
|
|
[r8]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R8])),
|
|
|
|
[r9]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R9])),
|
|
|
|
[r10]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R10])),
|
|
|
|
[r11]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R11])),
|
|
|
|
[r12]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R12])),
|
|
|
|
[r13]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R13])),
|
|
|
|
[r14]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R14])),
|
|
|
|
[r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
#endif
|
2011-01-06 16:09:12 +00:00
|
|
|
[cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)),
|
|
|
|
[wordsize]"i"(sizeof(ulong))
|
KVM: VMX: Let gcc to choose which registers to save (x86_64)
This patch lets GCC to determine which registers to save when we
switch to/from a VCPU in the case of intel x86_64.
* Original code saves following registers:
rax, rbx, rcx, rdx, rsi, rdi, rbp,
r8, r9, r10, r11, r12, r13, r14, r15
* Patched code:
- informs GCC that we modify following registers
using the clobber description:
rbx, rdi, rsi,
r8, r9, r10, r11, r12, r13, r14, r15
- doesn't save rax because it is an output operand (vmx->fail)
- cannot put rcx in clobber description because it is an input operand,
but as we modify it and we want to keep its value (vcpu), we must
save it (pop/push)
- rbp is saved (pop/push) because GCC seems to ignore its use in the clobber
description.
- rdx is saved (pop/push) because it is reserved by GCC (REGPARM) and
cannot be put in the clobber description.
- line "mov (%%rsp), %3 \n\t" has been removed because %3
is rcx and rcx is restored just after.
- line ASM_VMX_VMWRITE_RSP_RDX() is moved out of the ifdef/else/endif
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-25 12:18:52 +00:00
|
|
|
: "cc", "memory"
|
|
|
|
#ifdef CONFIG_X86_64
|
2012-09-16 12:10:58 +00:00
|
|
|
, "rax", "rbx", "rdi", "rsi"
|
KVM: VMX: Let gcc to choose which registers to save (x86_64)
This patch lets GCC to determine which registers to save when we
switch to/from a VCPU in the case of intel x86_64.
* Original code saves following registers:
rax, rbx, rcx, rdx, rsi, rdi, rbp,
r8, r9, r10, r11, r12, r13, r14, r15
* Patched code:
- informs GCC that we modify following registers
using the clobber description:
rbx, rdi, rsi,
r8, r9, r10, r11, r12, r13, r14, r15
- doesn't save rax because it is an output operand (vmx->fail)
- cannot put rcx in clobber description because it is an input operand,
but as we modify it and we want to keep its value (vcpu), we must
save it (pop/push)
- rbp is saved (pop/push) because GCC seems to ignore its use in the clobber
description.
- rdx is saved (pop/push) because it is reserved by GCC (REGPARM) and
cannot be put in the clobber description.
- line "mov (%%rsp), %3 \n\t" has been removed because %3
is rcx and rcx is restored just after.
- line ASM_VMX_VMWRITE_RSP_RDX() is moved out of the ifdef/else/endif
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-25 12:18:52 +00:00
|
|
|
, "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
2012-09-16 12:10:58 +00:00
|
|
|
#else
|
|
|
|
, "eax", "ebx", "edi", "esi"
|
KVM: VMX: Let gcc to choose which registers to save (x86_64)
This patch lets GCC to determine which registers to save when we
switch to/from a VCPU in the case of intel x86_64.
* Original code saves following registers:
rax, rbx, rcx, rdx, rsi, rdi, rbp,
r8, r9, r10, r11, r12, r13, r14, r15
* Patched code:
- informs GCC that we modify following registers
using the clobber description:
rbx, rdi, rsi,
r8, r9, r10, r11, r12, r13, r14, r15
- doesn't save rax because it is an output operand (vmx->fail)
- cannot put rcx in clobber description because it is an input operand,
but as we modify it and we want to keep its value (vcpu), we must
save it (pop/push)
- rbp is saved (pop/push) because GCC seems to ignore its use in the clobber
description.
- rdx is saved (pop/push) because it is reserved by GCC (REGPARM) and
cannot be put in the clobber description.
- line "mov (%%rsp), %3 \n\t" has been removed because %3
is rcx and rcx is restored just after.
- line ASM_VMX_VMWRITE_RSP_RDX() is moved out of the ifdef/else/endif
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-25 12:18:52 +00:00
|
|
|
#endif
|
|
|
|
);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2012-08-12 13:12:29 +00:00
|
|
|
/* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
|
|
|
|
if (debugctlmsr)
|
|
|
|
update_debugctlmsr(debugctlmsr);
|
|
|
|
|
KVM: VMX: Fix ds/es corruption on i386 with preemption
Commit b2da15ac26a0c ("KVM: VMX: Optimize %ds, %es reload") broke i386
in the following scenario:
vcpu_load
...
vmx_save_host_state
vmx_vcpu_run
(ds.rpl, es.rpl cleared by hardware)
interrupt
push ds, es # pushes bad ds, es
schedule
vmx_vcpu_put
vmx_load_host_state
reload ds, es (with __USER_DS)
pop ds, es # of other thread's stack
iret
# other thread runs
interrupt
push ds, es
schedule # back in vcpu thread
pop ds, es # now with rpl=0
iret
...
vcpu_put
resume_userspace
iret # clears ds, es due to mismatched rpl
(instead of resume_userspace, we might return with SYSEXIT and then
take an exception; when the exception IRETs we end up with cleared
ds, es)
Fix by avoiding the optimization on i386 and reloading ds, es on the
lightweight exit path.
Reported-by: Chris Clayron <chris2553@googlemail.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
2012-08-01 13:48:03 +00:00
|
|
|
#ifndef CONFIG_X86_64
|
|
|
|
/*
|
|
|
|
* The sysexit path does not restore ds/es, so we must set them to
|
|
|
|
* a reasonable value ourselves.
|
|
|
|
*
|
|
|
|
* We can't defer this to vmx_load_host_state() since that function
|
|
|
|
* may be executed in interrupt context, which saves and restore segments
|
|
|
|
* around it, nullifying its effect.
|
|
|
|
*/
|
|
|
|
loadsegment(ds, __USER_DS);
|
|
|
|
loadsegment(es, __USER_DS);
|
|
|
|
#endif
|
|
|
|
|
2009-05-31 19:58:47 +00:00
|
|
|
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
|
2011-03-07 10:51:22 +00:00
|
|
|
| (1 << VCPU_EXREG_RFLAGS)
|
2010-12-05 16:56:11 +00:00
|
|
|
| (1 << VCPU_EXREG_PDPTR)
|
2011-04-27 16:42:18 +00:00
|
|
|
| (1 << VCPU_EXREG_SEGMENTS)
|
2010-12-05 16:56:11 +00:00
|
|
|
| (1 << VCPU_EXREG_CR3));
|
2008-06-27 17:58:02 +00:00
|
|
|
vcpu->arch.regs_dirty = 0;
|
|
|
|
|
2007-11-22 09:30:47 +00:00
|
|
|
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
|
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
vmx->loaded_vmcs->launched = 1;
|
2007-10-09 10:12:19 +00:00
|
|
|
|
2010-07-20 11:31:20 +00:00
|
|
|
vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
|
2011-09-12 08:52:24 +00:00
|
|
|
trace_kvm_exit(vmx->exit_reason, vcpu, KVM_ISA_VMX);
|
2010-07-20 11:31:20 +00:00
|
|
|
|
2013-09-25 09:51:33 +00:00
|
|
|
/*
|
|
|
|
* the KVM_REQ_EVENT optimization bit is only on for one entry, and if
|
|
|
|
* we did not inject a still-pending event to L1 now because of
|
|
|
|
* nested_run_pending, we need to re-enable this bit.
|
|
|
|
*/
|
|
|
|
if (vmx->nested.nested_run_pending)
|
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
|
|
|
|
|
|
|
vmx->nested.nested_run_pending = 0;
|
|
|
|
|
2010-07-20 11:31:20 +00:00
|
|
|
vmx_complete_atomic_exit(vmx);
|
|
|
|
vmx_recover_nmi_blocking(vmx);
|
2008-07-01 13:20:21 +00:00
|
|
|
vmx_complete_interrupts(vmx);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2014-07-17 10:25:16 +00:00
|
|
|
static void vmx_load_vmcs01(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int cpu;
|
|
|
|
|
|
|
|
if (vmx->loaded_vmcs == &vmx->vmcs01)
|
|
|
|
return;
|
|
|
|
|
|
|
|
cpu = get_cpu();
|
|
|
|
vmx->loaded_vmcs = &vmx->vmcs01;
|
|
|
|
vmx_vcpu_put(vcpu);
|
|
|
|
vmx_vcpu_load(vcpu, cpu);
|
|
|
|
vcpu->cpu = cpu;
|
|
|
|
put_cpu();
|
|
|
|
}
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2007-07-27 07:16:56 +00:00
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
if (enable_pml)
|
|
|
|
vmx_disable_pml(vmx);
|
2010-04-17 08:41:47 +00:00
|
|
|
free_vpid(vmx);
|
2014-07-17 10:25:16 +00:00
|
|
|
leave_guest_mode(vcpu);
|
|
|
|
vmx_load_vmcs01(vcpu);
|
2014-01-03 19:00:51 +00:00
|
|
|
free_nested(vmx);
|
2014-07-17 10:25:16 +00:00
|
|
|
free_loaded_vmcs(vmx->loaded_vmcs);
|
2007-07-27 07:16:56 +00:00
|
|
|
kfree(vmx->guest_msrs);
|
|
|
|
kvm_vcpu_uninit(vcpu);
|
2007-08-01 04:46:11 +00:00
|
|
|
kmem_cache_free(kvm_vcpu_cache, vmx);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2007-07-27 07:16:56 +00:00
|
|
|
static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
{
|
2007-07-27 07:16:56 +00:00
|
|
|
int err;
|
2007-07-30 11:12:19 +00:00
|
|
|
struct vcpu_vmx *vmx = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
|
2007-07-11 15:17:21 +00:00
|
|
|
int cpu;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
if (!vmx)
|
2007-07-27 07:16:56 +00:00
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
2008-01-17 07:14:33 +00:00
|
|
|
allocate_vpid(vmx);
|
|
|
|
|
2007-07-27 07:16:56 +00:00
|
|
|
err = kvm_vcpu_init(&vmx->vcpu, kvm, id);
|
|
|
|
if (err)
|
|
|
|
goto free_vcpu;
|
2007-01-06 00:36:23 +00:00
|
|
|
|
2007-07-27 12:13:10 +00:00
|
|
|
vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
2014-07-24 12:21:57 +00:00
|
|
|
BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
|
|
|
|
> PAGE_SIZE);
|
2014-07-24 12:06:56 +00:00
|
|
|
|
2011-04-12 23:27:55 +00:00
|
|
|
err = -ENOMEM;
|
2007-07-27 07:16:56 +00:00
|
|
|
if (!vmx->guest_msrs) {
|
|
|
|
goto uninit_vcpu;
|
|
|
|
}
|
2007-01-06 00:36:23 +00:00
|
|
|
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
vmx->loaded_vmcs = &vmx->vmcs01;
|
|
|
|
vmx->loaded_vmcs->vmcs = alloc_vmcs();
|
|
|
|
if (!vmx->loaded_vmcs->vmcs)
|
2007-07-27 07:16:56 +00:00
|
|
|
goto free_msrs;
|
KVM: VMX: Keep list of loaded VMCSs, instead of vcpus
In VMX, before we bring down a CPU we must VMCLEAR all VMCSs loaded on it
because (at least in theory) the processor might not have written all of its
content back to memory. Since a patch from June 26, 2008, this is done using
a per-cpu "vcpus_on_cpu" linked list of vcpus loaded on each CPU.
The problem is that with nested VMX, we no longer have the concept of a
vcpu being loaded on a cpu: A vcpu has multiple VMCSs (one for L1, a pool for
L2s), and each of those may be have been last loaded on a different cpu.
So instead of linking the vcpus, we link the VMCSs, using a new structure
loaded_vmcs. This structure contains the VMCS, and the information pertaining
to its loading on a specific cpu (namely, the cpu number, and whether it
was already launched on this cpu once). In nested we will also use the same
structure to hold L2 VMCSs, and vmx->loaded_vmcs is a pointer to the
currently active VMCS.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Acked-by: Acked-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-05-24 12:26:10 +00:00
|
|
|
if (!vmm_exclusive)
|
|
|
|
kvm_cpu_vmxon(__pa(per_cpu(vmxarea, raw_smp_processor_id())));
|
|
|
|
loaded_vmcs_init(vmx->loaded_vmcs);
|
|
|
|
if (!vmm_exclusive)
|
|
|
|
kvm_cpu_vmxoff();
|
2007-07-27 12:13:10 +00:00
|
|
|
|
2007-07-11 15:17:21 +00:00
|
|
|
cpu = get_cpu();
|
|
|
|
vmx_vcpu_load(&vmx->vcpu, cpu);
|
2010-08-20 08:07:23 +00:00
|
|
|
vmx->vcpu.cpu = cpu;
|
2007-07-30 06:31:43 +00:00
|
|
|
err = vmx_vcpu_setup(vmx);
|
2007-07-27 07:16:56 +00:00
|
|
|
vmx_vcpu_put(&vmx->vcpu);
|
2007-07-11 15:17:21 +00:00
|
|
|
put_cpu();
|
2007-07-27 07:16:56 +00:00
|
|
|
if (err)
|
|
|
|
goto free_vmcs;
|
2015-07-29 10:05:37 +00:00
|
|
|
if (cpu_need_virtualize_apic_accesses(&vmx->vcpu)) {
|
2011-04-12 23:27:55 +00:00
|
|
|
err = alloc_apic_access_page(kvm);
|
|
|
|
if (err)
|
2008-02-14 23:21:43 +00:00
|
|
|
goto free_vmcs;
|
2013-04-08 09:07:46 +00:00
|
|
|
}
|
2007-07-27 07:16:56 +00:00
|
|
|
|
2009-07-21 02:42:48 +00:00
|
|
|
if (enable_ept) {
|
|
|
|
if (!kvm->arch.ept_identity_map_addr)
|
|
|
|
kvm->arch.ept_identity_map_addr =
|
|
|
|
VMX_EPT_IDENTITY_PAGETABLE_ADDR;
|
2014-09-16 10:41:59 +00:00
|
|
|
err = init_rmode_identity_map(kvm);
|
|
|
|
if (err)
|
2011-02-21 10:07:59 +00:00
|
|
|
goto free_vmcs;
|
2009-07-21 02:42:48 +00:00
|
|
|
}
|
2008-04-25 13:44:52 +00:00
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
if (nested)
|
|
|
|
nested_vmx_setup_ctls_msrs(vmx);
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
vmx->nested.posted_intr_nv = -1;
|
2011-05-25 20:03:55 +00:00
|
|
|
vmx->nested.current_vmptr = -1ull;
|
|
|
|
vmx->nested.current_vmcs12 = NULL;
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
/*
|
|
|
|
* If PML is turned on, failure on enabling PML just results in failure
|
|
|
|
* of creating the vcpu, therefore we can simplify PML logic (by
|
|
|
|
* avoiding dealing with cases, such as enabling PML partially on vcpus
|
|
|
|
* for the guest, etc.
|
|
|
|
*/
|
|
|
|
if (enable_pml) {
|
|
|
|
err = vmx_enable_pml(vmx);
|
|
|
|
if (err)
|
|
|
|
goto free_vmcs;
|
|
|
|
}
|
|
|
|
|
2007-07-27 07:16:56 +00:00
|
|
|
return &vmx->vcpu;
|
|
|
|
|
|
|
|
free_vmcs:
|
2012-05-14 06:58:58 +00:00
|
|
|
free_loaded_vmcs(vmx->loaded_vmcs);
|
2007-07-27 07:16:56 +00:00
|
|
|
free_msrs:
|
|
|
|
kfree(vmx->guest_msrs);
|
|
|
|
uninit_vcpu:
|
|
|
|
kvm_vcpu_uninit(&vmx->vcpu);
|
|
|
|
free_vcpu:
|
2010-04-17 08:41:47 +00:00
|
|
|
free_vpid(vmx);
|
2007-08-01 04:46:11 +00:00
|
|
|
kmem_cache_free(kvm_vcpu_cache, vmx);
|
2007-07-27 07:16:56 +00:00
|
|
|
return ERR_PTR(err);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
2007-07-31 11:23:01 +00:00
|
|
|
static void __init vmx_check_processor_compat(void *rtn)
|
|
|
|
{
|
|
|
|
struct vmcs_config vmcs_conf;
|
|
|
|
|
|
|
|
*(int *)rtn = 0;
|
|
|
|
if (setup_vmcs_config(&vmcs_conf) < 0)
|
|
|
|
*(int *)rtn = -EIO;
|
|
|
|
if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) {
|
|
|
|
printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n",
|
|
|
|
smp_processor_id());
|
|
|
|
*(int *)rtn = -EIO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-25 02:20:22 +00:00
|
|
|
static int get_ept_level(void)
|
|
|
|
{
|
|
|
|
return VMX_EPT_DEFAULT_GAW + 1;
|
|
|
|
}
|
|
|
|
|
2009-04-27 12:35:42 +00:00
|
|
|
static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
|
2008-10-09 08:01:57 +00:00
|
|
|
{
|
2015-06-15 08:55:21 +00:00
|
|
|
u8 cache;
|
|
|
|
u64 ipat = 0;
|
2009-04-27 12:35:42 +00:00
|
|
|
|
2009-04-27 12:35:43 +00:00
|
|
|
/* For VT-d and EPT combination
|
2015-10-01 11:12:47 +00:00
|
|
|
* 1. MMIO: always map as UC
|
2009-04-27 12:35:43 +00:00
|
|
|
* 2. EPT with VT-d:
|
|
|
|
* a. VT-d without snooping control feature: can't guarantee the
|
2015-10-01 11:12:47 +00:00
|
|
|
* result, try to trust guest.
|
2009-04-27 12:35:43 +00:00
|
|
|
* b. VT-d with snooping control feature: snooping control feature of
|
|
|
|
* VT-d engine can guarantee the cache correctness. Just set it
|
|
|
|
* to WB to keep consistent with host. So the same as item 3.
|
2010-02-09 08:41:53 +00:00
|
|
|
* 3. EPT without VT-d: always map as WB and set IPAT=1 to keep
|
2009-04-27 12:35:43 +00:00
|
|
|
* consistent with host MTRR
|
|
|
|
*/
|
2015-10-01 11:12:47 +00:00
|
|
|
if (is_mmio) {
|
|
|
|
cache = MTRR_TYPE_UNCACHABLE;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!kvm_arch_has_noncoherent_dma(vcpu->kvm)) {
|
2015-06-15 08:55:21 +00:00
|
|
|
ipat = VMX_EPT_IPAT_BIT;
|
|
|
|
cache = MTRR_TYPE_WRBACK;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (kvm_read_cr0(vcpu) & X86_CR0_CD) {
|
|
|
|
ipat = VMX_EPT_IPAT_BIT;
|
2015-07-23 06:24:42 +00:00
|
|
|
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
|
2015-07-15 19:25:56 +00:00
|
|
|
cache = MTRR_TYPE_WRBACK;
|
|
|
|
else
|
|
|
|
cache = MTRR_TYPE_UNCACHABLE;
|
2015-06-15 08:55:21 +00:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
2015-06-15 08:55:22 +00:00
|
|
|
cache = kvm_mtrr_get_guest_memory_type(vcpu, gfn);
|
2015-06-15 08:55:21 +00:00
|
|
|
|
|
|
|
exit:
|
|
|
|
return (cache << VMX_EPT_MT_EPTE_SHIFT) | ipat;
|
2008-10-09 08:01:57 +00:00
|
|
|
}
|
|
|
|
|
2010-01-05 11:02:27 +00:00
|
|
|
static int vmx_get_lpage_level(void)
|
2009-07-27 14:30:48 +00:00
|
|
|
{
|
2010-01-05 11:02:29 +00:00
|
|
|
if (enable_ept && !cpu_has_vmx_ept_1g_page())
|
|
|
|
return PT_DIRECTORY_LEVEL;
|
|
|
|
else
|
|
|
|
/* For shadow and EPT supported 1GB page */
|
|
|
|
return PT_PDPE_LEVEL;
|
2009-07-27 14:30:48 +00:00
|
|
|
}
|
|
|
|
|
2009-12-18 08:48:46 +00:00
|
|
|
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2009-12-18 08:48:47 +00:00
|
|
|
struct kvm_cpuid_entry2 *best;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
u32 exec_control;
|
|
|
|
|
|
|
|
vmx->rdtscp_enabled = false;
|
|
|
|
if (vmx_rdtscp_supported()) {
|
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
if (exec_control & SECONDARY_EXEC_RDTSCP) {
|
|
|
|
best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
|
|
|
|
if (best && (best->edx & bit(X86_FEATURE_RDTSCP)))
|
|
|
|
vmx->rdtscp_enabled = true;
|
|
|
|
else {
|
|
|
|
exec_control &= ~SECONDARY_EXEC_RDTSCP;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
|
|
|
|
exec_control);
|
|
|
|
}
|
|
|
|
}
|
2015-03-23 18:27:19 +00:00
|
|
|
if (nested && !vmx->rdtscp_enabled)
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
|
|
~SECONDARY_EXEC_RDTSCP;
|
2009-12-18 08:48:47 +00:00
|
|
|
}
|
2012-07-02 01:18:48 +00:00
|
|
|
|
|
|
|
/* Exposing INVPCID only when PCID is exposed */
|
|
|
|
best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
|
|
|
|
if (vmx_invpcid_supported() &&
|
2012-09-07 07:36:59 +00:00
|
|
|
best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
|
2012-07-02 01:18:48 +00:00
|
|
|
guest_cpuid_has_pcid(vcpu)) {
|
2012-11-09 14:20:17 +00:00
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
2012-07-02 01:18:48 +00:00
|
|
|
exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
|
|
|
|
exec_control);
|
|
|
|
} else {
|
2012-11-09 14:20:17 +00:00
|
|
|
if (cpu_has_secondary_exec_ctrls()) {
|
|
|
|
exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
|
|
|
|
exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
|
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
|
|
|
|
exec_control);
|
|
|
|
}
|
2012-07-02 01:18:48 +00:00
|
|
|
if (best)
|
2012-09-07 07:36:59 +00:00
|
|
|
best->ebx &= ~bit(X86_FEATURE_INVPCID);
|
2012-07-02 01:18:48 +00:00
|
|
|
}
|
2009-12-18 08:48:46 +00:00
|
|
|
}
|
|
|
|
|
2010-04-22 10:33:11 +00:00
|
|
|
static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
|
|
|
|
{
|
2011-05-25 20:16:10 +00:00
|
|
|
if (func == 1 && nested)
|
|
|
|
entry->ecx |= bit(X86_FEATURE_VMX);
|
2010-04-22 10:33:11 +00:00
|
|
|
}
|
|
|
|
|
2013-08-06 09:00:32 +00:00
|
|
|
static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
|
|
|
|
struct x86_exception *fault)
|
|
|
|
{
|
2014-01-04 17:47:20 +00:00
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
u32 exit_reason;
|
2013-08-06 09:00:32 +00:00
|
|
|
|
|
|
|
if (fault->error_code & PFERR_RSVD_MASK)
|
2014-01-04 17:47:20 +00:00
|
|
|
exit_reason = EXIT_REASON_EPT_MISCONFIG;
|
2013-08-06 09:00:32 +00:00
|
|
|
else
|
2014-01-04 17:47:20 +00:00
|
|
|
exit_reason = EXIT_REASON_EPT_VIOLATION;
|
|
|
|
nested_vmx_vmexit(vcpu, exit_reason, 0, vcpu->arch.exit_qualification);
|
2013-08-06 09:00:32 +00:00
|
|
|
vmcs12->guest_physical_address = fault->address;
|
|
|
|
}
|
|
|
|
|
2013-08-05 08:07:16 +00:00
|
|
|
/* Callbacks for nested_ept_init_mmu_context: */
|
|
|
|
|
|
|
|
static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
/* return the page table to be shadowed - in our case, EPT12 */
|
|
|
|
return get_vmcs12(vcpu)->ept_pointer;
|
|
|
|
}
|
|
|
|
|
2013-10-02 14:56:13 +00:00
|
|
|
static void nested_ept_init_mmu_context(struct kvm_vcpu *vcpu)
|
2013-08-05 08:07:16 +00:00
|
|
|
{
|
2013-10-02 14:56:14 +00:00
|
|
|
WARN_ON(mmu_is_nested(vcpu));
|
|
|
|
kvm_init_shadow_ept_mmu(vcpu,
|
2015-02-03 15:56:30 +00:00
|
|
|
to_vmx(vcpu)->nested.nested_vmx_ept_caps &
|
|
|
|
VMX_EPT_EXECUTE_ONLY_BIT);
|
2013-08-05 08:07:16 +00:00
|
|
|
vcpu->arch.mmu.set_cr3 = vmx_set_cr3;
|
|
|
|
vcpu->arch.mmu.get_cr3 = nested_ept_get_cr3;
|
|
|
|
vcpu->arch.mmu.inject_page_fault = nested_ept_inject_page_fault;
|
|
|
|
|
|
|
|
vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
vcpu->arch.walk_mmu = &vcpu->arch.mmu;
|
|
|
|
}
|
|
|
|
|
2014-12-16 19:35:53 +00:00
|
|
|
static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
|
|
|
|
u16 error_code)
|
|
|
|
{
|
|
|
|
bool inequality, bit;
|
|
|
|
|
|
|
|
bit = (vmcs12->exception_bitmap & (1u << PF_VECTOR)) != 0;
|
|
|
|
inequality =
|
|
|
|
(error_code & vmcs12->page_fault_error_code_mask) !=
|
|
|
|
vmcs12->page_fault_error_code_match;
|
|
|
|
return inequality ^ bit;
|
|
|
|
}
|
|
|
|
|
2013-09-25 09:51:36 +00:00
|
|
|
static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu,
|
|
|
|
struct x86_exception *fault)
|
|
|
|
{
|
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
|
|
|
|
WARN_ON(!is_guest_mode(vcpu));
|
|
|
|
|
2014-12-16 19:35:53 +00:00
|
|
|
if (nested_vmx_is_page_fault_vmexit(vmcs12, fault->error_code))
|
2014-01-04 17:47:20 +00:00
|
|
|
nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
|
|
|
|
vmcs_read32(VM_EXIT_INTR_INFO),
|
|
|
|
vmcs_readl(EXIT_QUALIFICATION));
|
2013-09-25 09:51:36 +00:00
|
|
|
else
|
|
|
|
kvm_inject_page_fault(vcpu, fault);
|
|
|
|
}
|
|
|
|
|
2014-08-21 11:46:49 +00:00
|
|
|
static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
2015-03-29 20:56:27 +00:00
|
|
|
int maxphyaddr = cpuid_maxphyaddr(vcpu);
|
2014-08-21 11:46:49 +00:00
|
|
|
|
|
|
|
if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
|
2015-03-29 20:56:27 +00:00
|
|
|
if (!PAGE_ALIGNED(vmcs12->apic_access_addr) ||
|
|
|
|
vmcs12->apic_access_addr >> maxphyaddr)
|
2014-08-21 11:46:49 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Translate L1 physical address to host physical
|
|
|
|
* address for vmcs02. Keep the page pinned, so this
|
|
|
|
* physical address remains valid. We keep a reference
|
|
|
|
* to it so we can release it later.
|
|
|
|
*/
|
|
|
|
if (vmx->nested.apic_access_page) /* shouldn't happen */
|
|
|
|
nested_release_page(vmx->nested.apic_access_page);
|
|
|
|
vmx->nested.apic_access_page =
|
|
|
|
nested_get_page(vcpu, vmcs12->apic_access_addr);
|
|
|
|
}
|
2014-08-21 11:46:50 +00:00
|
|
|
|
|
|
|
if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) {
|
2015-03-29 20:56:27 +00:00
|
|
|
if (!PAGE_ALIGNED(vmcs12->virtual_apic_page_addr) ||
|
|
|
|
vmcs12->virtual_apic_page_addr >> maxphyaddr)
|
2014-08-21 11:46:50 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (vmx->nested.virtual_apic_page) /* shouldn't happen */
|
|
|
|
nested_release_page(vmx->nested.virtual_apic_page);
|
|
|
|
vmx->nested.virtual_apic_page =
|
|
|
|
nested_get_page(vcpu, vmcs12->virtual_apic_page_addr);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Failing the vm entry is _not_ what the processor does
|
|
|
|
* but it's basically the only possibility we have.
|
|
|
|
* We could still enter the guest if CR8 load exits are
|
|
|
|
* enabled, CR8 store exits are enabled, and virtualize APIC
|
|
|
|
* access is disabled; in this case the processor would never
|
|
|
|
* use the TPR shadow and we could simply clear the bit from
|
|
|
|
* the execution control. But such a configuration is useless,
|
|
|
|
* so let's keep the code simple.
|
|
|
|
*/
|
|
|
|
if (!vmx->nested.virtual_apic_page)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
if (nested_cpu_has_posted_intr(vmcs12)) {
|
2015-03-29 20:56:27 +00:00
|
|
|
if (!IS_ALIGNED(vmcs12->posted_intr_desc_addr, 64) ||
|
|
|
|
vmcs12->posted_intr_desc_addr >> maxphyaddr)
|
2015-02-03 15:58:17 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (vmx->nested.pi_desc_page) { /* shouldn't happen */
|
|
|
|
kunmap(vmx->nested.pi_desc_page);
|
|
|
|
nested_release_page(vmx->nested.pi_desc_page);
|
|
|
|
}
|
|
|
|
vmx->nested.pi_desc_page =
|
|
|
|
nested_get_page(vcpu, vmcs12->posted_intr_desc_addr);
|
|
|
|
if (!vmx->nested.pi_desc_page)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
vmx->nested.pi_desc =
|
|
|
|
(struct pi_desc *)kmap(vmx->nested.pi_desc_page);
|
|
|
|
if (!vmx->nested.pi_desc) {
|
|
|
|
nested_release_page_clean(vmx->nested.pi_desc_page);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
vmx->nested.pi_desc =
|
|
|
|
(struct pi_desc *)((void *)vmx->nested.pi_desc +
|
|
|
|
(unsigned long)(vmcs12->posted_intr_desc_addr &
|
|
|
|
(PAGE_SIZE - 1)));
|
|
|
|
}
|
|
|
|
|
2014-08-21 11:46:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
static void vmx_start_preemption_timer(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
u64 preemption_timeout = get_vmcs12(vcpu)->vmx_preemption_timer_value;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
|
|
if (vcpu->arch.virtual_tsc_khz == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Make sure short timeouts reliably trigger an immediate vmexit.
|
|
|
|
* hrtimer_start does not guarantee this. */
|
|
|
|
if (preemption_timeout <= 1) {
|
|
|
|
vmx_preemption_timer_fn(&vmx->nested.preemption_timer);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
preemption_timeout <<= VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE;
|
|
|
|
preemption_timeout *= 1000000;
|
|
|
|
do_div(preemption_timeout, vcpu->arch.virtual_tsc_khz);
|
|
|
|
hrtimer_start(&vmx->nested.preemption_timer,
|
|
|
|
ns_to_ktime(preemption_timeout), HRTIMER_MODE_REL);
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:49:31 +00:00
|
|
|
static int nested_vmx_check_msr_bitmap_controls(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
int maxphyaddr;
|
|
|
|
u64 addr;
|
|
|
|
|
|
|
|
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_MSR_BITMAPS))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (vmcs12_read_any(vcpu, MSR_BITMAP, &addr)) {
|
|
|
|
WARN_ON(1);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
maxphyaddr = cpuid_maxphyaddr(vcpu);
|
|
|
|
|
|
|
|
if (!PAGE_ALIGNED(vmcs12->msr_bitmap) ||
|
|
|
|
((addr + PAGE_SIZE) >> maxphyaddr))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Merge L0's and L1's MSR bitmap, return false to indicate that
|
|
|
|
* we do not use the hardware.
|
|
|
|
*/
|
|
|
|
static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
2015-02-03 15:57:18 +00:00
|
|
|
int msr;
|
2015-02-03 15:56:03 +00:00
|
|
|
struct page *page;
|
|
|
|
unsigned long *msr_bitmap;
|
|
|
|
|
|
|
|
if (!nested_cpu_has_virt_x2apic_mode(vmcs12))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
page = nested_get_page(vcpu, vmcs12->msr_bitmap);
|
|
|
|
if (!page) {
|
|
|
|
WARN_ON(1);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
msr_bitmap = (unsigned long *)kmap(page);
|
|
|
|
if (!msr_bitmap) {
|
|
|
|
nested_release_page_clean(page);
|
|
|
|
WARN_ON(1);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nested_cpu_has_virt_x2apic_mode(vmcs12)) {
|
2015-02-03 15:57:18 +00:00
|
|
|
if (nested_cpu_has_apic_reg_virt(vmcs12))
|
|
|
|
for (msr = 0x800; msr <= 0x8ff; msr++)
|
|
|
|
nested_vmx_disable_intercept_for_msr(
|
|
|
|
msr_bitmap,
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
msr, MSR_TYPE_R);
|
2015-02-03 15:56:03 +00:00
|
|
|
/* TPR is allowed */
|
|
|
|
nested_vmx_disable_intercept_for_msr(msr_bitmap,
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
APIC_BASE_MSR + (APIC_TASKPRI >> 4),
|
|
|
|
MSR_TYPE_R | MSR_TYPE_W);
|
2015-02-03 15:57:51 +00:00
|
|
|
if (nested_cpu_has_vid(vmcs12)) {
|
|
|
|
/* EOI and self-IPI are allowed */
|
|
|
|
nested_vmx_disable_intercept_for_msr(
|
|
|
|
msr_bitmap,
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
APIC_BASE_MSR + (APIC_EOI >> 4),
|
|
|
|
MSR_TYPE_W);
|
|
|
|
nested_vmx_disable_intercept_for_msr(
|
|
|
|
msr_bitmap,
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
APIC_BASE_MSR + (APIC_SELF_IPI >> 4),
|
|
|
|
MSR_TYPE_W);
|
|
|
|
}
|
2015-02-03 15:57:18 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Enable reading intercept of all the x2apic
|
|
|
|
* MSRs. We should not rely on vmcs12 to do any
|
|
|
|
* optimizations here, it may have been modified
|
|
|
|
* by L1.
|
|
|
|
*/
|
|
|
|
for (msr = 0x800; msr <= 0x8ff; msr++)
|
|
|
|
__vmx_enable_intercept_for_msr(
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
msr,
|
|
|
|
MSR_TYPE_R);
|
|
|
|
|
2015-02-03 15:56:03 +00:00
|
|
|
__vmx_enable_intercept_for_msr(
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
APIC_BASE_MSR + (APIC_TASKPRI >> 4),
|
2015-02-03 15:57:18 +00:00
|
|
|
MSR_TYPE_W);
|
2015-02-03 15:57:51 +00:00
|
|
|
__vmx_enable_intercept_for_msr(
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
APIC_BASE_MSR + (APIC_EOI >> 4),
|
|
|
|
MSR_TYPE_W);
|
|
|
|
__vmx_enable_intercept_for_msr(
|
|
|
|
vmx_msr_bitmap_nested,
|
|
|
|
APIC_BASE_MSR + (APIC_SELF_IPI >> 4),
|
|
|
|
MSR_TYPE_W);
|
2015-02-03 15:57:18 +00:00
|
|
|
}
|
2015-02-03 15:56:03 +00:00
|
|
|
kunmap(page);
|
|
|
|
nested_release_page_clean(page);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nested_vmx_check_apicv_controls(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
2015-02-03 15:57:18 +00:00
|
|
|
if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
|
2015-02-03 15:57:51 +00:00
|
|
|
!nested_cpu_has_apic_reg_virt(vmcs12) &&
|
2015-02-03 15:58:17 +00:00
|
|
|
!nested_cpu_has_vid(vmcs12) &&
|
|
|
|
!nested_cpu_has_posted_intr(vmcs12))
|
2015-02-03 15:56:03 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If virtualize x2apic mode is enabled,
|
|
|
|
* virtualize apic access must be disabled.
|
|
|
|
*/
|
2015-02-03 15:57:18 +00:00
|
|
|
if (nested_cpu_has_virt_x2apic_mode(vmcs12) &&
|
|
|
|
nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
|
2015-02-03 15:56:03 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2015-02-03 15:57:51 +00:00
|
|
|
/*
|
|
|
|
* If virtual interrupt delivery is enabled,
|
|
|
|
* we must exit on external interrupts.
|
|
|
|
*/
|
|
|
|
if (nested_cpu_has_vid(vmcs12) &&
|
|
|
|
!nested_exit_on_intr(vcpu))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
/*
|
|
|
|
* bits 15:8 should be zero in posted_intr_nv,
|
|
|
|
* the descriptor address has been already checked
|
|
|
|
* in nested_get_vmcs12_pages.
|
|
|
|
*/
|
|
|
|
if (nested_cpu_has_posted_intr(vmcs12) &&
|
|
|
|
(!nested_cpu_has_vid(vmcs12) ||
|
|
|
|
!nested_exit_intr_ack_set(vcpu) ||
|
|
|
|
vmcs12->posted_intr_nv & 0xff00))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2015-02-03 15:56:03 +00:00
|
|
|
/* tpr shadow is needed by all apicv features. */
|
|
|
|
if (!nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
2015-02-03 15:49:31 +00:00
|
|
|
}
|
|
|
|
|
2014-12-11 05:53:27 +00:00
|
|
|
static int nested_vmx_check_msr_switch(struct kvm_vcpu *vcpu,
|
|
|
|
unsigned long count_field,
|
2015-03-29 20:56:44 +00:00
|
|
|
unsigned long addr_field)
|
2014-12-11 05:52:58 +00:00
|
|
|
{
|
2015-03-29 20:56:44 +00:00
|
|
|
int maxphyaddr;
|
2014-12-11 05:53:27 +00:00
|
|
|
u64 count, addr;
|
|
|
|
|
|
|
|
if (vmcs12_read_any(vcpu, count_field, &count) ||
|
|
|
|
vmcs12_read_any(vcpu, addr_field, &addr)) {
|
|
|
|
WARN_ON(1);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (count == 0)
|
|
|
|
return 0;
|
2015-03-29 20:56:44 +00:00
|
|
|
maxphyaddr = cpuid_maxphyaddr(vcpu);
|
2014-12-11 05:53:27 +00:00
|
|
|
if (!IS_ALIGNED(addr, 16) || addr >> maxphyaddr ||
|
|
|
|
(addr + count * sizeof(struct vmx_msr_entry) - 1) >> maxphyaddr) {
|
|
|
|
pr_warn_ratelimited(
|
|
|
|
"nVMX: invalid MSR switch (0x%lx, %d, %llu, 0x%08llx)",
|
|
|
|
addr_field, maxphyaddr, count, addr);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nested_vmx_check_msr_switch_controls(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
if (vmcs12->vm_exit_msr_load_count == 0 &&
|
|
|
|
vmcs12->vm_exit_msr_store_count == 0 &&
|
|
|
|
vmcs12->vm_entry_msr_load_count == 0)
|
|
|
|
return 0; /* Fast path */
|
|
|
|
if (nested_vmx_check_msr_switch(vcpu, VM_EXIT_MSR_LOAD_COUNT,
|
2015-03-29 20:56:44 +00:00
|
|
|
VM_EXIT_MSR_LOAD_ADDR) ||
|
2014-12-11 05:53:27 +00:00
|
|
|
nested_vmx_check_msr_switch(vcpu, VM_EXIT_MSR_STORE_COUNT,
|
2015-03-29 20:56:44 +00:00
|
|
|
VM_EXIT_MSR_STORE_ADDR) ||
|
2014-12-11 05:53:27 +00:00
|
|
|
nested_vmx_check_msr_switch(vcpu, VM_ENTRY_MSR_LOAD_COUNT,
|
2015-03-29 20:56:44 +00:00
|
|
|
VM_ENTRY_MSR_LOAD_ADDR))
|
2014-12-11 05:53:27 +00:00
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nested_vmx_msr_check_common(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmx_msr_entry *e)
|
|
|
|
{
|
|
|
|
/* x2APIC MSR accesses are not allowed */
|
2015-05-04 06:32:32 +00:00
|
|
|
if (vcpu->arch.apic_base & X2APIC_ENABLE && e->index >> 8 == 0x8)
|
2014-12-11 05:53:27 +00:00
|
|
|
return -EINVAL;
|
|
|
|
if (e->index == MSR_IA32_UCODE_WRITE || /* SDM Table 35-2 */
|
|
|
|
e->index == MSR_IA32_UCODE_REV)
|
|
|
|
return -EINVAL;
|
|
|
|
if (e->reserved != 0)
|
2014-12-11 05:52:58 +00:00
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-12-11 05:53:27 +00:00
|
|
|
static int nested_vmx_load_msr_check(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmx_msr_entry *e)
|
2014-12-11 05:52:58 +00:00
|
|
|
{
|
|
|
|
if (e->index == MSR_FS_BASE ||
|
|
|
|
e->index == MSR_GS_BASE ||
|
2014-12-11 05:53:27 +00:00
|
|
|
e->index == MSR_IA32_SMM_MONITOR_CTL || /* SMM is not supported */
|
|
|
|
nested_vmx_msr_check_common(vcpu, e))
|
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nested_vmx_store_msr_check(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmx_msr_entry *e)
|
|
|
|
{
|
|
|
|
if (e->index == MSR_IA32_SMBASE || /* SMM is not supported */
|
|
|
|
nested_vmx_msr_check_common(vcpu, e))
|
2014-12-11 05:52:58 +00:00
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Load guest's/host's msr at nested entry/exit.
|
|
|
|
* return 0 for success, entry index for failure.
|
|
|
|
*/
|
|
|
|
static u32 nested_vmx_load_msr(struct kvm_vcpu *vcpu, u64 gpa, u32 count)
|
|
|
|
{
|
|
|
|
u32 i;
|
|
|
|
struct vmx_msr_entry e;
|
|
|
|
struct msr_data msr;
|
|
|
|
|
|
|
|
msr.host_initiated = false;
|
|
|
|
for (i = 0; i < count; i++) {
|
2015-04-08 13:39:23 +00:00
|
|
|
if (kvm_vcpu_read_guest(vcpu, gpa + i * sizeof(e),
|
|
|
|
&e, sizeof(e))) {
|
2014-12-11 05:53:27 +00:00
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s cannot read MSR entry (%u, 0x%08llx)\n",
|
|
|
|
__func__, i, gpa + i * sizeof(e));
|
2014-12-11 05:52:58 +00:00
|
|
|
goto fail;
|
2014-12-11 05:53:27 +00:00
|
|
|
}
|
|
|
|
if (nested_vmx_load_msr_check(vcpu, &e)) {
|
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s check failed (%u, 0x%x, 0x%x)\n",
|
|
|
|
__func__, i, e.index, e.reserved);
|
|
|
|
goto fail;
|
|
|
|
}
|
2014-12-11 05:52:58 +00:00
|
|
|
msr.index = e.index;
|
|
|
|
msr.data = e.value;
|
2014-12-11 05:53:27 +00:00
|
|
|
if (kvm_set_msr(vcpu, &msr)) {
|
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s cannot write MSR (%u, 0x%x, 0x%llx)\n",
|
|
|
|
__func__, i, e.index, e.value);
|
2014-12-11 05:52:58 +00:00
|
|
|
goto fail;
|
2014-12-11 05:53:27 +00:00
|
|
|
}
|
2014-12-11 05:52:58 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
fail:
|
|
|
|
return i + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int nested_vmx_store_msr(struct kvm_vcpu *vcpu, u64 gpa, u32 count)
|
|
|
|
{
|
|
|
|
u32 i;
|
|
|
|
struct vmx_msr_entry e;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
2015-04-08 13:30:38 +00:00
|
|
|
struct msr_data msr_info;
|
2015-04-08 13:39:23 +00:00
|
|
|
if (kvm_vcpu_read_guest(vcpu,
|
|
|
|
gpa + i * sizeof(e),
|
|
|
|
&e, 2 * sizeof(u32))) {
|
2014-12-11 05:53:27 +00:00
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s cannot read MSR entry (%u, 0x%08llx)\n",
|
|
|
|
__func__, i, gpa + i * sizeof(e));
|
2014-12-11 05:52:58 +00:00
|
|
|
return -EINVAL;
|
2014-12-11 05:53:27 +00:00
|
|
|
}
|
|
|
|
if (nested_vmx_store_msr_check(vcpu, &e)) {
|
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s check failed (%u, 0x%x, 0x%x)\n",
|
|
|
|
__func__, i, e.index, e.reserved);
|
2014-12-11 05:52:58 +00:00
|
|
|
return -EINVAL;
|
2014-12-11 05:53:27 +00:00
|
|
|
}
|
2015-04-08 13:30:38 +00:00
|
|
|
msr_info.host_initiated = false;
|
|
|
|
msr_info.index = e.index;
|
|
|
|
if (kvm_get_msr(vcpu, &msr_info)) {
|
2014-12-11 05:53:27 +00:00
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s cannot read MSR (%u, 0x%x)\n",
|
|
|
|
__func__, i, e.index);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2015-04-08 13:39:23 +00:00
|
|
|
if (kvm_vcpu_write_guest(vcpu,
|
|
|
|
gpa + i * sizeof(e) +
|
|
|
|
offsetof(struct vmx_msr_entry, value),
|
|
|
|
&msr_info.data, sizeof(msr_info.data))) {
|
2014-12-11 05:53:27 +00:00
|
|
|
pr_warn_ratelimited(
|
|
|
|
"%s cannot write MSR (%u, 0x%x, 0x%llx)\n",
|
2015-04-08 13:30:38 +00:00
|
|
|
__func__, i, e.index, msr_info.data);
|
2014-12-11 05:53:27 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2014-12-11 05:52:58 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
/*
|
|
|
|
* prepare_vmcs02 is called when the L1 guest hypervisor runs its nested
|
|
|
|
* L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it
|
2014-09-22 02:31:38 +00:00
|
|
|
* with L0's requirements for its guest (a.k.a. vmcs01), so we can run the L2
|
2011-05-25 20:10:02 +00:00
|
|
|
* guest in a way that will both be appropriate to L1's requests, and our
|
|
|
|
* needs. In addition to modifying the active vmcs (which is vmcs02), this
|
|
|
|
* function also has additional necessary side-effects, like setting various
|
|
|
|
* vcpu->arch fields.
|
|
|
|
*/
|
|
|
|
static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
u32 exec_control;
|
|
|
|
|
|
|
|
vmcs_write16(GUEST_ES_SELECTOR, vmcs12->guest_es_selector);
|
|
|
|
vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector);
|
|
|
|
vmcs_write16(GUEST_SS_SELECTOR, vmcs12->guest_ss_selector);
|
|
|
|
vmcs_write16(GUEST_DS_SELECTOR, vmcs12->guest_ds_selector);
|
|
|
|
vmcs_write16(GUEST_FS_SELECTOR, vmcs12->guest_fs_selector);
|
|
|
|
vmcs_write16(GUEST_GS_SELECTOR, vmcs12->guest_gs_selector);
|
|
|
|
vmcs_write16(GUEST_LDTR_SELECTOR, vmcs12->guest_ldtr_selector);
|
|
|
|
vmcs_write16(GUEST_TR_SELECTOR, vmcs12->guest_tr_selector);
|
|
|
|
vmcs_write32(GUEST_ES_LIMIT, vmcs12->guest_es_limit);
|
|
|
|
vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit);
|
|
|
|
vmcs_write32(GUEST_SS_LIMIT, vmcs12->guest_ss_limit);
|
|
|
|
vmcs_write32(GUEST_DS_LIMIT, vmcs12->guest_ds_limit);
|
|
|
|
vmcs_write32(GUEST_FS_LIMIT, vmcs12->guest_fs_limit);
|
|
|
|
vmcs_write32(GUEST_GS_LIMIT, vmcs12->guest_gs_limit);
|
|
|
|
vmcs_write32(GUEST_LDTR_LIMIT, vmcs12->guest_ldtr_limit);
|
|
|
|
vmcs_write32(GUEST_TR_LIMIT, vmcs12->guest_tr_limit);
|
|
|
|
vmcs_write32(GUEST_GDTR_LIMIT, vmcs12->guest_gdtr_limit);
|
|
|
|
vmcs_write32(GUEST_IDTR_LIMIT, vmcs12->guest_idtr_limit);
|
|
|
|
vmcs_write32(GUEST_ES_AR_BYTES, vmcs12->guest_es_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_CS_AR_BYTES, vmcs12->guest_cs_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_DS_AR_BYTES, vmcs12->guest_ds_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_FS_AR_BYTES, vmcs12->guest_fs_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_GS_AR_BYTES, vmcs12->guest_gs_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_LDTR_AR_BYTES, vmcs12->guest_ldtr_ar_bytes);
|
|
|
|
vmcs_write32(GUEST_TR_AR_BYTES, vmcs12->guest_tr_ar_bytes);
|
|
|
|
vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base);
|
|
|
|
vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base);
|
|
|
|
vmcs_writel(GUEST_SS_BASE, vmcs12->guest_ss_base);
|
|
|
|
vmcs_writel(GUEST_DS_BASE, vmcs12->guest_ds_base);
|
|
|
|
vmcs_writel(GUEST_FS_BASE, vmcs12->guest_fs_base);
|
|
|
|
vmcs_writel(GUEST_GS_BASE, vmcs12->guest_gs_base);
|
|
|
|
vmcs_writel(GUEST_LDTR_BASE, vmcs12->guest_ldtr_base);
|
|
|
|
vmcs_writel(GUEST_TR_BASE, vmcs12->guest_tr_base);
|
|
|
|
vmcs_writel(GUEST_GDTR_BASE, vmcs12->guest_gdtr_base);
|
|
|
|
vmcs_writel(GUEST_IDTR_BASE, vmcs12->guest_idtr_base);
|
|
|
|
|
2014-06-16 11:59:43 +00:00
|
|
|
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) {
|
|
|
|
kvm_set_dr(vcpu, 7, vmcs12->guest_dr7);
|
|
|
|
vmcs_write64(GUEST_IA32_DEBUGCTL, vmcs12->guest_ia32_debugctl);
|
|
|
|
} else {
|
|
|
|
kvm_set_dr(vcpu, 7, vcpu->arch.dr7);
|
|
|
|
vmcs_write64(GUEST_IA32_DEBUGCTL, vmx->nested.vmcs01_debugctl);
|
|
|
|
}
|
2011-05-25 20:10:02 +00:00
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
|
|
|
|
vmcs12->vm_entry_intr_info_field);
|
|
|
|
vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE,
|
|
|
|
vmcs12->vm_entry_exception_error_code);
|
|
|
|
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
|
|
|
|
vmcs12->vm_entry_instruction_len);
|
|
|
|
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
|
|
|
|
vmcs12->guest_interruptibility_info);
|
|
|
|
vmcs_write32(GUEST_SYSENTER_CS, vmcs12->guest_sysenter_cs);
|
2013-07-28 15:31:06 +00:00
|
|
|
vmx_set_rflags(vcpu, vmcs12->guest_rflags);
|
2011-05-25 20:10:02 +00:00
|
|
|
vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS,
|
|
|
|
vmcs12->guest_pending_dbg_exceptions);
|
|
|
|
vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp);
|
|
|
|
vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->guest_sysenter_eip);
|
|
|
|
|
2014-12-04 11:11:07 +00:00
|
|
|
if (nested_cpu_has_xsaves(vmcs12))
|
|
|
|
vmcs_write64(XSS_EXIT_BITMAP, vmcs12->xss_exit_bitmap);
|
2011-05-25 20:10:02 +00:00
|
|
|
vmcs_write64(VMCS_LINK_POINTER, -1ull);
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
exec_control = vmcs12->pin_based_vm_exec_control;
|
|
|
|
exec_control |= vmcs_config.pin_based_exec_ctrl;
|
2015-02-03 15:58:17 +00:00
|
|
|
exec_control &= ~PIN_BASED_VMX_PREEMPTION_TIMER;
|
|
|
|
|
|
|
|
if (nested_cpu_has_posted_intr(vmcs12)) {
|
|
|
|
/*
|
|
|
|
* Note that we use L0's vector here and in
|
|
|
|
* vmx_deliver_nested_posted_interrupt.
|
|
|
|
*/
|
|
|
|
vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv;
|
|
|
|
vmx->nested.pi_pending = false;
|
|
|
|
vmcs_write64(POSTED_INTR_NV, POSTED_INTR_VECTOR);
|
|
|
|
vmcs_write64(POSTED_INTR_DESC_ADDR,
|
|
|
|
page_to_phys(vmx->nested.pi_desc_page) +
|
|
|
|
(unsigned long)(vmcs12->posted_intr_desc_addr &
|
|
|
|
(PAGE_SIZE - 1)));
|
|
|
|
} else
|
|
|
|
exec_control &= ~PIN_BASED_POSTED_INTR;
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, exec_control);
|
2011-05-25 20:10:02 +00:00
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
vmx->nested.preemption_timer_expired = false;
|
|
|
|
if (nested_cpu_has_preemption_timer(vmcs12))
|
|
|
|
vmx_start_preemption_timer(vcpu);
|
2013-03-13 10:31:24 +00:00
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
/*
|
|
|
|
* Whether page-faults are trapped is determined by a combination of
|
|
|
|
* 3 settings: PFEC_MASK, PFEC_MATCH and EXCEPTION_BITMAP.PF.
|
|
|
|
* If enable_ept, L0 doesn't care about page faults and we should
|
|
|
|
* set all of these to L1's desires. However, if !enable_ept, L0 does
|
|
|
|
* care about (at least some) page faults, and because it is not easy
|
|
|
|
* (if at all possible?) to merge L0 and L1's desires, we simply ask
|
|
|
|
* to exit on each and every L2 page fault. This is done by setting
|
|
|
|
* MASK=MATCH=0 and (see below) EB.PF=1.
|
|
|
|
* Note that below we don't need special code to set EB.PF beyond the
|
|
|
|
* "or"ing of the EB of vmcs01 and vmcs12, because when enable_ept,
|
|
|
|
* vmcs01's EB.PF is 0 so the "or" will take vmcs12's value, and when
|
|
|
|
* !enable_ept, EB.PF is 1, so the "or" will always be 1.
|
|
|
|
*
|
|
|
|
* A problem with this approach (when !enable_ept) is that L1 may be
|
|
|
|
* injected with more page faults than it asked for. This could have
|
|
|
|
* caused problems, but in practice existing hypervisors don't care.
|
|
|
|
* To fix this, we will need to emulate the PFEC checking (on the L1
|
|
|
|
* page tables), using walk_addr(), when injecting PFs to L1.
|
|
|
|
*/
|
|
|
|
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK,
|
|
|
|
enable_ept ? vmcs12->page_fault_error_code_mask : 0);
|
|
|
|
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH,
|
|
|
|
enable_ept ? vmcs12->page_fault_error_code_match : 0);
|
|
|
|
|
|
|
|
if (cpu_has_secondary_exec_ctrls()) {
|
2014-03-07 19:03:13 +00:00
|
|
|
exec_control = vmx_secondary_exec_control(vmx);
|
2011-05-25 20:10:02 +00:00
|
|
|
if (!vmx->rdtscp_enabled)
|
|
|
|
exec_control &= ~SECONDARY_EXEC_RDTSCP;
|
|
|
|
/* Take the following fields only from vmcs12 */
|
2014-05-07 09:20:54 +00:00
|
|
|
exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
|
2015-03-23 18:27:19 +00:00
|
|
|
SECONDARY_EXEC_RDTSCP |
|
2014-05-07 09:20:54 +00:00
|
|
|
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
|
2015-03-23 18:27:19 +00:00
|
|
|
SECONDARY_EXEC_APIC_REGISTER_VIRT);
|
2011-05-25 20:10:02 +00:00
|
|
|
if (nested_cpu_has(vmcs12,
|
|
|
|
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS))
|
|
|
|
exec_control |= vmcs12->secondary_vm_exec_control;
|
|
|
|
|
|
|
|
if (exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) {
|
|
|
|
/*
|
|
|
|
* If translation failed, no matter: This feature asks
|
|
|
|
* to exit when accessing the given address, and if it
|
|
|
|
* can never be accessed, this feature won't do
|
|
|
|
* anything anyway.
|
|
|
|
*/
|
|
|
|
if (!vmx->nested.apic_access_page)
|
|
|
|
exec_control &=
|
|
|
|
~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
|
|
else
|
|
|
|
vmcs_write64(APIC_ACCESS_ADDR,
|
|
|
|
page_to_phys(vmx->nested.apic_access_page));
|
2015-02-03 15:56:03 +00:00
|
|
|
} else if (!(nested_cpu_has_virt_x2apic_mode(vmcs12)) &&
|
2015-07-29 10:05:37 +00:00
|
|
|
cpu_need_virtualize_apic_accesses(&vmx->vcpu)) {
|
2013-12-16 11:55:46 +00:00
|
|
|
exec_control |=
|
|
|
|
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
2014-09-24 07:57:54 +00:00
|
|
|
kvm_vcpu_reload_apic_access_page(vcpu);
|
2011-05-25 20:10:02 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 15:57:51 +00:00
|
|
|
if (exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY) {
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP0,
|
|
|
|
vmcs12->eoi_exit_bitmap0);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP1,
|
|
|
|
vmcs12->eoi_exit_bitmap1);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP2,
|
|
|
|
vmcs12->eoi_exit_bitmap2);
|
|
|
|
vmcs_write64(EOI_EXIT_BITMAP3,
|
|
|
|
vmcs12->eoi_exit_bitmap3);
|
|
|
|
vmcs_write16(GUEST_INTR_STATUS,
|
|
|
|
vmcs12->guest_intr_status);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set host-state according to L0's settings (vmcs12 is irrelevant here)
|
|
|
|
* Some constant fields are set here by vmx_set_constant_host_state().
|
|
|
|
* Other fields are different per CPU, and will be set later when
|
|
|
|
* vmx_vcpu_load() is called, and when vmx_save_host_state() is called.
|
|
|
|
*/
|
2013-04-11 11:25:10 +00:00
|
|
|
vmx_set_constant_host_state(vmx);
|
2011-05-25 20:10:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* HOST_RSP is normally set correctly in vmx_vcpu_run() just before
|
|
|
|
* entry, but only if the current (host) sp changed from the value
|
|
|
|
* we wrote last (vmx->host_rsp). This cache is no longer relevant
|
|
|
|
* if we switch vmcs, and rather than hold a separate cache per vmcs,
|
|
|
|
* here we just force the write to happen on entry.
|
|
|
|
*/
|
|
|
|
vmx->host_rsp = 0;
|
|
|
|
|
|
|
|
exec_control = vmx_exec_control(vmx); /* L0's desires */
|
|
|
|
exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
|
|
|
|
exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
|
|
|
|
exec_control &= ~CPU_BASED_TPR_SHADOW;
|
|
|
|
exec_control |= vmcs12->cpu_based_vm_exec_control;
|
2014-08-21 11:46:50 +00:00
|
|
|
|
|
|
|
if (exec_control & CPU_BASED_TPR_SHADOW) {
|
|
|
|
vmcs_write64(VIRTUAL_APIC_PAGE_ADDR,
|
|
|
|
page_to_phys(vmx->nested.virtual_apic_page));
|
|
|
|
vmcs_write32(TPR_THRESHOLD, vmcs12->tpr_threshold);
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:49:31 +00:00
|
|
|
if (cpu_has_vmx_msr_bitmap() &&
|
2015-03-04 06:31:56 +00:00
|
|
|
exec_control & CPU_BASED_USE_MSR_BITMAPS) {
|
|
|
|
nested_vmx_merge_msr_bitmap(vcpu, vmcs12);
|
|
|
|
/* MSR_BITMAP will be set by following vmx_set_efer. */
|
2015-02-03 15:49:31 +00:00
|
|
|
} else
|
|
|
|
exec_control &= ~CPU_BASED_USE_MSR_BITMAPS;
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
/*
|
2015-02-03 15:49:31 +00:00
|
|
|
* Merging of IO bitmap not currently supported.
|
2011-05-25 20:10:02 +00:00
|
|
|
* Rather, exit every time.
|
|
|
|
*/
|
|
|
|
exec_control &= ~CPU_BASED_USE_IO_BITMAPS;
|
|
|
|
exec_control |= CPU_BASED_UNCOND_IO_EXITING;
|
|
|
|
|
|
|
|
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
|
|
|
|
|
|
|
|
/* EXCEPTION_BITMAP and CR0_GUEST_HOST_MASK should basically be the
|
|
|
|
* bitwise-or of what L1 wants to trap for L2, and what we want to
|
|
|
|
* trap. Note that CR0.TS also needs updating - we do this later.
|
|
|
|
*/
|
|
|
|
update_exception_bitmap(vcpu);
|
|
|
|
vcpu->arch.cr0_guest_owned_bits &= ~vmcs12->cr0_guest_host_mask;
|
|
|
|
vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
|
|
|
|
|
2013-08-05 08:07:06 +00:00
|
|
|
/* L2->L1 exit controls are emulated - the hardware exit is to L0 so
|
|
|
|
* we should use its exit controls. Note that VM_EXIT_LOAD_IA32_EFER
|
|
|
|
* bits are further modified by vmx_set_efer() below.
|
|
|
|
*/
|
2014-03-07 19:03:13 +00:00
|
|
|
vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_ctrl);
|
2013-08-05 08:07:06 +00:00
|
|
|
|
|
|
|
/* vmcs12's VM_ENTRY_LOAD_IA32_EFER and VM_ENTRY_IA32E_MODE are
|
|
|
|
* emulated by vmx_set_efer(), below.
|
|
|
|
*/
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_init(vmx,
|
2013-08-05 08:07:06 +00:00
|
|
|
(vmcs12->vm_entry_controls & ~VM_ENTRY_LOAD_IA32_EFER &
|
|
|
|
~VM_ENTRY_IA32E_MODE) |
|
2011-05-25 20:10:02 +00:00
|
|
|
(vmcs_config.vmentry_ctrl & ~VM_ENTRY_IA32E_MODE));
|
|
|
|
|
2013-08-04 15:17:27 +00:00
|
|
|
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT) {
|
2011-05-25 20:10:02 +00:00
|
|
|
vmcs_write64(GUEST_IA32_PAT, vmcs12->guest_ia32_pat);
|
2013-08-04 15:17:27 +00:00
|
|
|
vcpu->arch.pat = vmcs12->guest_ia32_pat;
|
|
|
|
} else if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT)
|
2011-05-25 20:10:02 +00:00
|
|
|
vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat);
|
|
|
|
|
|
|
|
|
|
|
|
set_cr4_guest_host_mask(vmx);
|
|
|
|
|
2014-02-24 11:30:04 +00:00
|
|
|
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)
|
|
|
|
vmcs_write64(GUEST_BNDCFGS, vmcs12->guest_bndcfgs);
|
|
|
|
|
2011-08-02 12:54:52 +00:00
|
|
|
if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
|
|
|
|
vmcs_write64(TSC_OFFSET,
|
|
|
|
vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset);
|
|
|
|
else
|
|
|
|
vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
|
2011-05-25 20:10:02 +00:00
|
|
|
|
|
|
|
if (enable_vpid) {
|
|
|
|
/*
|
|
|
|
* Trivially support vpid by letting L2s share their parent
|
|
|
|
* L1's vpid. TODO: move to a more elaborate solution, giving
|
|
|
|
* each L2 its own vpid and exposing the vpid feature to L1.
|
|
|
|
*/
|
|
|
|
vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
|
|
|
|
vmx_flush_tlb(vcpu);
|
|
|
|
}
|
|
|
|
|
2013-08-05 08:07:16 +00:00
|
|
|
if (nested_cpu_has_ept(vmcs12)) {
|
|
|
|
kvm_mmu_unload(vcpu);
|
|
|
|
nested_ept_init_mmu_context(vcpu);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)
|
|
|
|
vcpu->arch.efer = vmcs12->guest_ia32_efer;
|
2013-04-14 10:44:54 +00:00
|
|
|
else if (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE)
|
2011-05-25 20:10:02 +00:00
|
|
|
vcpu->arch.efer |= (EFER_LMA | EFER_LME);
|
|
|
|
else
|
|
|
|
vcpu->arch.efer &= ~(EFER_LMA | EFER_LME);
|
|
|
|
/* Note: modifies VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
|
|
|
|
vmx_set_efer(vcpu, vcpu->arch.efer);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets GUEST_CR0 to vmcs12->guest_cr0, with possibly a modified
|
|
|
|
* TS bit (for lazy fpu) and bits which we consider mandatory enabled.
|
|
|
|
* The CR0_READ_SHADOW is what L2 should have expected to read given
|
|
|
|
* the specifications by L1; It's not enough to take
|
|
|
|
* vmcs12->cr0_read_shadow because on our cr0_guest_host_mask we we
|
|
|
|
* have more bits than L1 expected.
|
|
|
|
*/
|
|
|
|
vmx_set_cr0(vcpu, vmcs12->guest_cr0);
|
|
|
|
vmcs_writel(CR0_READ_SHADOW, nested_read_cr0(vmcs12));
|
|
|
|
|
|
|
|
vmx_set_cr4(vcpu, vmcs12->guest_cr4);
|
|
|
|
vmcs_writel(CR4_READ_SHADOW, nested_read_cr4(vmcs12));
|
|
|
|
|
|
|
|
/* shadow page tables on either EPT or shadow page tables */
|
|
|
|
kvm_set_cr3(vcpu, vmcs12->guest_cr3);
|
|
|
|
kvm_mmu_reset_context(vcpu);
|
|
|
|
|
2013-09-25 09:51:36 +00:00
|
|
|
if (!enable_ept)
|
|
|
|
vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested;
|
|
|
|
|
2013-08-05 08:07:07 +00:00
|
|
|
/*
|
|
|
|
* L1 may access the L2's PDPTR, so save them to construct vmcs12
|
|
|
|
*/
|
|
|
|
if (enable_ept) {
|
|
|
|
vmcs_write64(GUEST_PDPTR0, vmcs12->guest_pdptr0);
|
|
|
|
vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1);
|
|
|
|
vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2);
|
|
|
|
vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:02 +00:00
|
|
|
kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp);
|
|
|
|
kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->guest_rip);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:10:33 +00:00
|
|
|
/*
|
|
|
|
* nested_vmx_run() handles a nested entry, i.e., a VMLAUNCH or VMRESUME on L1
|
|
|
|
* for running an L2 nested guest.
|
|
|
|
*/
|
|
|
|
static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
|
|
|
|
{
|
|
|
|
struct vmcs12 *vmcs12;
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
int cpu;
|
|
|
|
struct loaded_vmcs *vmcs02;
|
2013-04-20 08:52:36 +00:00
|
|
|
bool ia32e;
|
2014-12-11 05:52:58 +00:00
|
|
|
u32 msr_entry_idx;
|
2011-05-25 20:10:33 +00:00
|
|
|
|
|
|
|
if (!nested_vmx_check_permission(vcpu) ||
|
|
|
|
!nested_vmx_check_vmcs12(vcpu))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
skip_emulated_instruction(vcpu);
|
|
|
|
vmcs12 = get_vmcs12(vcpu);
|
|
|
|
|
2013-04-18 11:39:25 +00:00
|
|
|
if (enable_shadow_vmcs)
|
|
|
|
copy_shadow_to_vmcs12(vmx);
|
|
|
|
|
2011-05-25 20:12:04 +00:00
|
|
|
/*
|
|
|
|
* The nested entry process starts with enforcing various prerequisites
|
|
|
|
* on vmcs12 as required by the Intel SDM, and act appropriately when
|
|
|
|
* they fail: As the SDM explains, some conditions should cause the
|
|
|
|
* instruction to fail, while others will cause the instruction to seem
|
|
|
|
* to succeed, but return an EXIT_REASON_INVALID_STATE.
|
|
|
|
* To speed up the normal (success) code path, we should avoid checking
|
|
|
|
* for misconfigurations which will anyway be caught by the processor
|
|
|
|
* when using the merged vmcs02.
|
|
|
|
*/
|
|
|
|
if (vmcs12->launch_state == launch) {
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
launch ? VMXERR_VMLAUNCH_NONCLEAR_VMCS
|
|
|
|
: VMXERR_VMRESUME_NONLAUNCHED_VMCS);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-12-04 07:58:54 +00:00
|
|
|
if (vmcs12->guest_activity_state != GUEST_ACTIVITY_ACTIVE &&
|
|
|
|
vmcs12->guest_activity_state != GUEST_ACTIVITY_HLT) {
|
2013-04-15 13:00:27 +00:00
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:49:31 +00:00
|
|
|
if (!nested_get_vmcs12_pages(vcpu, vmcs12)) {
|
2011-05-25 20:12:04 +00:00
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:49:31 +00:00
|
|
|
if (nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12)) {
|
2011-05-25 20:12:04 +00:00
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:56:03 +00:00
|
|
|
if (nested_vmx_check_apicv_controls(vcpu, vmcs12)) {
|
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-12-11 05:53:27 +00:00
|
|
|
if (nested_vmx_check_msr_switch_controls(vcpu, vmcs12)) {
|
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:12:04 +00:00
|
|
|
if (!vmx_control_verify(vmcs12->cpu_based_vm_exec_control,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_true_procbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_procbased_ctls_high) ||
|
2011-05-25 20:12:04 +00:00
|
|
|
!vmx_control_verify(vmcs12->secondary_vm_exec_control,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_secondary_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high) ||
|
2011-05-25 20:12:04 +00:00
|
|
|
!vmx_control_verify(vmcs12->pin_based_vm_exec_control,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_pinbased_ctls_high) ||
|
2011-05-25 20:12:04 +00:00
|
|
|
!vmx_control_verify(vmcs12->vm_exit_controls,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_true_exit_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_exit_ctls_high) ||
|
2011-05-25 20:12:04 +00:00
|
|
|
!vmx_control_verify(vmcs12->vm_entry_controls,
|
2015-02-03 15:56:30 +00:00
|
|
|
vmx->nested.nested_vmx_true_entry_ctls_low,
|
|
|
|
vmx->nested.nested_vmx_entry_ctls_high))
|
2011-05-25 20:12:04 +00:00
|
|
|
{
|
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((vmcs12->host_cr0 & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON) ||
|
|
|
|
((vmcs12->host_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) {
|
|
|
|
nested_vmx_failValid(vcpu,
|
|
|
|
VMXERR_ENTRY_INVALID_HOST_STATE_FIELD);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:56:30 +00:00
|
|
|
if (!nested_cr0_valid(vcpu, vmcs12->guest_cr0) ||
|
2011-05-25 20:12:04 +00:00
|
|
|
((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) {
|
|
|
|
nested_vmx_entry_failure(vcpu, vmcs12,
|
|
|
|
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (vmcs12->vmcs_link_pointer != -1ull) {
|
|
|
|
nested_vmx_entry_failure(vcpu, vmcs12,
|
|
|
|
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_VMCS_LINK_PTR);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-20 08:52:36 +00:00
|
|
|
/*
|
2013-04-27 10:58:00 +00:00
|
|
|
* If the load IA32_EFER VM-entry control is 1, the following checks
|
2013-04-20 08:52:36 +00:00
|
|
|
* are performed on the field for the IA32_EFER MSR:
|
|
|
|
* - Bits reserved in the IA32_EFER MSR must be 0.
|
|
|
|
* - Bit 10 (corresponding to IA32_EFER.LMA) must equal the value of
|
|
|
|
* the IA-32e mode guest VM-exit control. It must also be identical
|
|
|
|
* to bit 8 (LME) if bit 31 in the CR0 field (corresponding to
|
|
|
|
* CR0.PG) is 1.
|
|
|
|
*/
|
|
|
|
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER) {
|
|
|
|
ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
|
|
|
|
if (!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer) ||
|
|
|
|
ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA) ||
|
|
|
|
((vmcs12->guest_cr0 & X86_CR0_PG) &&
|
|
|
|
ia32e != !!(vmcs12->guest_ia32_efer & EFER_LME))) {
|
|
|
|
nested_vmx_entry_failure(vcpu, vmcs12,
|
|
|
|
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the load IA32_EFER VM-exit control is 1, bits reserved in the
|
|
|
|
* IA32_EFER MSR must be 0 in the field for that register. In addition,
|
|
|
|
* the values of the LMA and LME bits in the field must each be that of
|
|
|
|
* the host address-space size VM-exit control.
|
|
|
|
*/
|
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER) {
|
|
|
|
ia32e = (vmcs12->vm_exit_controls &
|
|
|
|
VM_EXIT_HOST_ADDR_SPACE_SIZE) != 0;
|
|
|
|
if (!kvm_valid_efer(vcpu, vmcs12->host_ia32_efer) ||
|
|
|
|
ia32e != !!(vmcs12->host_ia32_efer & EFER_LMA) ||
|
|
|
|
ia32e != !!(vmcs12->host_ia32_efer & EFER_LME)) {
|
|
|
|
nested_vmx_entry_failure(vcpu, vmcs12,
|
|
|
|
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:12:04 +00:00
|
|
|
/*
|
|
|
|
* We're finally done with prerequisite checking, and can start with
|
|
|
|
* the nested entry.
|
|
|
|
*/
|
|
|
|
|
2011-05-25 20:10:33 +00:00
|
|
|
vmcs02 = nested_get_current_vmcs02(vmx);
|
|
|
|
if (!vmcs02)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
enter_guest_mode(vcpu);
|
|
|
|
|
|
|
|
vmx->nested.vmcs01_tsc_offset = vmcs_read64(TSC_OFFSET);
|
|
|
|
|
2014-06-16 11:59:43 +00:00
|
|
|
if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS))
|
|
|
|
vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
|
|
|
|
|
2011-05-25 20:10:33 +00:00
|
|
|
cpu = get_cpu();
|
|
|
|
vmx->loaded_vmcs = vmcs02;
|
|
|
|
vmx_vcpu_put(vcpu);
|
|
|
|
vmx_vcpu_load(vcpu, cpu);
|
|
|
|
vcpu->cpu = cpu;
|
|
|
|
put_cpu();
|
|
|
|
|
2013-02-23 21:35:37 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
|
|
|
|
2011-05-25 20:10:33 +00:00
|
|
|
prepare_vmcs02(vcpu, vmcs12);
|
|
|
|
|
2014-12-11 05:52:58 +00:00
|
|
|
msr_entry_idx = nested_vmx_load_msr(vcpu,
|
|
|
|
vmcs12->vm_entry_msr_load_addr,
|
|
|
|
vmcs12->vm_entry_msr_load_count);
|
|
|
|
if (msr_entry_idx) {
|
|
|
|
leave_guest_mode(vcpu);
|
|
|
|
vmx_load_vmcs01(vcpu);
|
|
|
|
nested_vmx_entry_failure(vcpu, vmcs12,
|
|
|
|
EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmcs12->launch_state = 1;
|
|
|
|
|
2013-12-04 07:58:54 +00:00
|
|
|
if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT)
|
2015-03-02 19:43:31 +00:00
|
|
|
return kvm_vcpu_halt(vcpu);
|
2013-12-04 07:58:54 +00:00
|
|
|
|
2014-01-04 17:47:23 +00:00
|
|
|
vmx->nested.nested_run_pending = 1;
|
|
|
|
|
2011-05-25 20:10:33 +00:00
|
|
|
/*
|
|
|
|
* Note no nested_vmx_succeed or nested_vmx_fail here. At this point
|
|
|
|
* we are no longer running L1, and VMLAUNCH/VMRESUME has not yet
|
|
|
|
* returned as far as L1 is concerned. It will only return (and set
|
|
|
|
* the success flag) when L2 exits (see nested_vmx_vmexit()).
|
|
|
|
*/
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
/*
|
|
|
|
* On a nested exit from L2 to L1, vmcs12.guest_cr0 might not be up-to-date
|
|
|
|
* because L2 may have changed some cr0 bits directly (CRO_GUEST_HOST_MASK).
|
|
|
|
* This function returns the new value we should put in vmcs12.guest_cr0.
|
|
|
|
* It's not enough to just return the vmcs02 GUEST_CR0. Rather,
|
|
|
|
* 1. Bits that neither L0 nor L1 trapped, were set directly by L2 and are now
|
|
|
|
* available in vmcs02 GUEST_CR0. (Note: It's enough to check that L0
|
|
|
|
* didn't trap the bit, because if L1 did, so would L0).
|
|
|
|
* 2. Bits that L1 asked to trap (and therefore L0 also did) could not have
|
|
|
|
* been modified by L2, and L1 knows it. So just leave the old value of
|
|
|
|
* the bit from vmcs12.guest_cr0. Note that the bit from vmcs02 GUEST_CR0
|
|
|
|
* isn't relevant, because if L0 traps this bit it can set it to anything.
|
|
|
|
* 3. Bits that L1 didn't trap, but L0 did. L1 believes the guest could have
|
|
|
|
* changed these bits, and therefore they need to be updated, but L0
|
|
|
|
* didn't necessarily allow them to be changed in GUEST_CR0 - and rather
|
|
|
|
* put them in vmcs02 CR0_READ_SHADOW. So take these bits from there.
|
|
|
|
*/
|
|
|
|
static inline unsigned long
|
|
|
|
vmcs12_guest_cr0(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return
|
|
|
|
/*1*/ (vmcs_readl(GUEST_CR0) & vcpu->arch.cr0_guest_owned_bits) |
|
|
|
|
/*2*/ (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask) |
|
|
|
|
/*3*/ (vmcs_readl(CR0_READ_SHADOW) & ~(vmcs12->cr0_guest_host_mask |
|
|
|
|
vcpu->arch.cr0_guest_owned_bits));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned long
|
|
|
|
vmcs12_guest_cr4(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
return
|
|
|
|
/*1*/ (vmcs_readl(GUEST_CR4) & vcpu->arch.cr4_guest_owned_bits) |
|
|
|
|
/*2*/ (vmcs12->guest_cr4 & vmcs12->cr4_guest_host_mask) |
|
|
|
|
/*3*/ (vmcs_readl(CR4_READ_SHADOW) & ~(vmcs12->cr4_guest_host_mask |
|
|
|
|
vcpu->arch.cr4_guest_owned_bits));
|
|
|
|
}
|
|
|
|
|
2013-04-14 10:12:46 +00:00
|
|
|
static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
|
|
|
{
|
|
|
|
u32 idt_vectoring;
|
|
|
|
unsigned int nr;
|
|
|
|
|
2013-09-25 09:51:34 +00:00
|
|
|
if (vcpu->arch.exception.pending && vcpu->arch.exception.reinject) {
|
2013-04-14 10:12:46 +00:00
|
|
|
nr = vcpu->arch.exception.nr;
|
|
|
|
idt_vectoring = nr | VECTORING_INFO_VALID_MASK;
|
|
|
|
|
|
|
|
if (kvm_exception_is_soft(nr)) {
|
|
|
|
vmcs12->vm_exit_instruction_len =
|
|
|
|
vcpu->arch.event_exit_inst_len;
|
|
|
|
idt_vectoring |= INTR_TYPE_SOFT_EXCEPTION;
|
|
|
|
} else
|
|
|
|
idt_vectoring |= INTR_TYPE_HARD_EXCEPTION;
|
|
|
|
|
|
|
|
if (vcpu->arch.exception.has_error_code) {
|
|
|
|
idt_vectoring |= VECTORING_INFO_DELIVER_CODE_MASK;
|
|
|
|
vmcs12->idt_vectoring_error_code =
|
|
|
|
vcpu->arch.exception.error_code;
|
|
|
|
}
|
|
|
|
|
|
|
|
vmcs12->idt_vectoring_info_field = idt_vectoring;
|
2013-10-23 16:42:15 +00:00
|
|
|
} else if (vcpu->arch.nmi_injected) {
|
2013-04-14 10:12:46 +00:00
|
|
|
vmcs12->idt_vectoring_info_field =
|
|
|
|
INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR;
|
|
|
|
} else if (vcpu->arch.interrupt.pending) {
|
|
|
|
nr = vcpu->arch.interrupt.nr;
|
|
|
|
idt_vectoring = nr | VECTORING_INFO_VALID_MASK;
|
|
|
|
|
|
|
|
if (vcpu->arch.interrupt.soft) {
|
|
|
|
idt_vectoring |= INTR_TYPE_SOFT_INTR;
|
|
|
|
vmcs12->vm_entry_instruction_len =
|
|
|
|
vcpu->arch.event_exit_inst_len;
|
|
|
|
} else
|
|
|
|
idt_vectoring |= INTR_TYPE_EXT_INTR;
|
|
|
|
|
|
|
|
vmcs12->idt_vectoring_info_field = idt_vectoring;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:12 +00:00
|
|
|
static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
|
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) &&
|
|
|
|
vmx->nested.preemption_timer_expired) {
|
|
|
|
if (vmx->nested.nested_run_pending)
|
|
|
|
return -EBUSY;
|
|
|
|
nested_vmx_vmexit(vcpu, EXIT_REASON_PREEMPTION_TIMER, 0, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:12 +00:00
|
|
|
if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) {
|
2014-03-07 19:03:14 +00:00
|
|
|
if (vmx->nested.nested_run_pending ||
|
|
|
|
vcpu->arch.interrupt.pending)
|
2014-03-07 19:03:12 +00:00
|
|
|
return -EBUSY;
|
|
|
|
nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
|
|
|
|
NMI_VECTOR | INTR_TYPE_NMI_INTR |
|
|
|
|
INTR_INFO_VALID_MASK, 0);
|
|
|
|
/*
|
|
|
|
* The NMI-triggered VM exit counts as injection:
|
|
|
|
* clear this one and block further NMIs.
|
|
|
|
*/
|
|
|
|
vcpu->arch.nmi_pending = 0;
|
|
|
|
vmx_set_nmi_mask(vcpu, true);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((kvm_cpu_has_interrupt(vcpu) || external_intr) &&
|
|
|
|
nested_exit_on_intr(vcpu)) {
|
|
|
|
if (vmx->nested.nested_run_pending)
|
|
|
|
return -EBUSY;
|
|
|
|
nested_vmx_vmexit(vcpu, EXIT_REASON_EXTERNAL_INTERRUPT, 0, 0);
|
2015-02-03 15:58:17 +00:00
|
|
|
return 0;
|
2014-03-07 19:03:12 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 15:58:17 +00:00
|
|
|
return vmx_complete_nested_posted_interrupt(vcpu);
|
2014-03-07 19:03:12 +00:00
|
|
|
}
|
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
static u32 vmx_get_preemption_timer_value(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
ktime_t remaining =
|
|
|
|
hrtimer_get_remaining(&to_vmx(vcpu)->nested.preemption_timer);
|
|
|
|
u64 value;
|
|
|
|
|
|
|
|
if (ktime_to_ns(remaining) <= 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
value = ktime_to_ns(remaining) * vcpu->arch.virtual_tsc_khz;
|
|
|
|
do_div(value, 1000000);
|
|
|
|
return value >> VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE;
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
/*
|
|
|
|
* prepare_vmcs12 is part of what we need to do when the nested L2 guest exits
|
|
|
|
* and we want to prepare to run its L1 parent. L1 keeps a vmcs for L2 (vmcs12),
|
|
|
|
* and this function updates it to reflect the changes to the guest state while
|
|
|
|
* L2 was running (and perhaps made some exits which were handled directly by L0
|
|
|
|
* without going back to L1), and to reflect the exit reason.
|
|
|
|
* Note that we do not have to copy here all VMCS fields, just those that
|
|
|
|
* could have changed by the L2 guest or the exit - i.e., the guest-state and
|
|
|
|
* exit-information fields only. Other fields are modified by L1 with VMWRITE,
|
|
|
|
* which already writes to vmcs12 directly.
|
|
|
|
*/
|
2014-01-04 17:47:20 +00:00
|
|
|
static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
|
|
|
u32 exit_reason, u32 exit_intr_info,
|
|
|
|
unsigned long exit_qualification)
|
2011-05-25 20:11:34 +00:00
|
|
|
{
|
|
|
|
/* update guest state fields: */
|
|
|
|
vmcs12->guest_cr0 = vmcs12_guest_cr0(vcpu, vmcs12);
|
|
|
|
vmcs12->guest_cr4 = vmcs12_guest_cr4(vcpu, vmcs12);
|
|
|
|
|
|
|
|
vmcs12->guest_rsp = kvm_register_read(vcpu, VCPU_REGS_RSP);
|
|
|
|
vmcs12->guest_rip = kvm_register_read(vcpu, VCPU_REGS_RIP);
|
|
|
|
vmcs12->guest_rflags = vmcs_readl(GUEST_RFLAGS);
|
|
|
|
|
|
|
|
vmcs12->guest_es_selector = vmcs_read16(GUEST_ES_SELECTOR);
|
|
|
|
vmcs12->guest_cs_selector = vmcs_read16(GUEST_CS_SELECTOR);
|
|
|
|
vmcs12->guest_ss_selector = vmcs_read16(GUEST_SS_SELECTOR);
|
|
|
|
vmcs12->guest_ds_selector = vmcs_read16(GUEST_DS_SELECTOR);
|
|
|
|
vmcs12->guest_fs_selector = vmcs_read16(GUEST_FS_SELECTOR);
|
|
|
|
vmcs12->guest_gs_selector = vmcs_read16(GUEST_GS_SELECTOR);
|
|
|
|
vmcs12->guest_ldtr_selector = vmcs_read16(GUEST_LDTR_SELECTOR);
|
|
|
|
vmcs12->guest_tr_selector = vmcs_read16(GUEST_TR_SELECTOR);
|
|
|
|
vmcs12->guest_es_limit = vmcs_read32(GUEST_ES_LIMIT);
|
|
|
|
vmcs12->guest_cs_limit = vmcs_read32(GUEST_CS_LIMIT);
|
|
|
|
vmcs12->guest_ss_limit = vmcs_read32(GUEST_SS_LIMIT);
|
|
|
|
vmcs12->guest_ds_limit = vmcs_read32(GUEST_DS_LIMIT);
|
|
|
|
vmcs12->guest_fs_limit = vmcs_read32(GUEST_FS_LIMIT);
|
|
|
|
vmcs12->guest_gs_limit = vmcs_read32(GUEST_GS_LIMIT);
|
|
|
|
vmcs12->guest_ldtr_limit = vmcs_read32(GUEST_LDTR_LIMIT);
|
|
|
|
vmcs12->guest_tr_limit = vmcs_read32(GUEST_TR_LIMIT);
|
|
|
|
vmcs12->guest_gdtr_limit = vmcs_read32(GUEST_GDTR_LIMIT);
|
|
|
|
vmcs12->guest_idtr_limit = vmcs_read32(GUEST_IDTR_LIMIT);
|
|
|
|
vmcs12->guest_es_ar_bytes = vmcs_read32(GUEST_ES_AR_BYTES);
|
|
|
|
vmcs12->guest_cs_ar_bytes = vmcs_read32(GUEST_CS_AR_BYTES);
|
|
|
|
vmcs12->guest_ss_ar_bytes = vmcs_read32(GUEST_SS_AR_BYTES);
|
|
|
|
vmcs12->guest_ds_ar_bytes = vmcs_read32(GUEST_DS_AR_BYTES);
|
|
|
|
vmcs12->guest_fs_ar_bytes = vmcs_read32(GUEST_FS_AR_BYTES);
|
|
|
|
vmcs12->guest_gs_ar_bytes = vmcs_read32(GUEST_GS_AR_BYTES);
|
|
|
|
vmcs12->guest_ldtr_ar_bytes = vmcs_read32(GUEST_LDTR_AR_BYTES);
|
|
|
|
vmcs12->guest_tr_ar_bytes = vmcs_read32(GUEST_TR_AR_BYTES);
|
|
|
|
vmcs12->guest_es_base = vmcs_readl(GUEST_ES_BASE);
|
|
|
|
vmcs12->guest_cs_base = vmcs_readl(GUEST_CS_BASE);
|
|
|
|
vmcs12->guest_ss_base = vmcs_readl(GUEST_SS_BASE);
|
|
|
|
vmcs12->guest_ds_base = vmcs_readl(GUEST_DS_BASE);
|
|
|
|
vmcs12->guest_fs_base = vmcs_readl(GUEST_FS_BASE);
|
|
|
|
vmcs12->guest_gs_base = vmcs_readl(GUEST_GS_BASE);
|
|
|
|
vmcs12->guest_ldtr_base = vmcs_readl(GUEST_LDTR_BASE);
|
|
|
|
vmcs12->guest_tr_base = vmcs_readl(GUEST_TR_BASE);
|
|
|
|
vmcs12->guest_gdtr_base = vmcs_readl(GUEST_GDTR_BASE);
|
|
|
|
vmcs12->guest_idtr_base = vmcs_readl(GUEST_IDTR_BASE);
|
|
|
|
|
|
|
|
vmcs12->guest_interruptibility_info =
|
|
|
|
vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
|
|
|
|
vmcs12->guest_pending_dbg_exceptions =
|
|
|
|
vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS);
|
2014-01-04 17:47:24 +00:00
|
|
|
if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
|
|
|
|
vmcs12->guest_activity_state = GUEST_ACTIVITY_HLT;
|
|
|
|
else
|
|
|
|
vmcs12->guest_activity_state = GUEST_ACTIVITY_ACTIVE;
|
2011-05-25 20:11:34 +00:00
|
|
|
|
2014-03-07 19:03:13 +00:00
|
|
|
if (nested_cpu_has_preemption_timer(vmcs12)) {
|
|
|
|
if (vmcs12->vm_exit_controls &
|
|
|
|
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)
|
|
|
|
vmcs12->vmx_preemption_timer_value =
|
|
|
|
vmx_get_preemption_timer_value(vcpu);
|
|
|
|
hrtimer_cancel(&to_vmx(vcpu)->nested.preemption_timer);
|
|
|
|
}
|
2013-09-16 08:11:44 +00:00
|
|
|
|
2013-08-05 08:07:07 +00:00
|
|
|
/*
|
|
|
|
* In some cases (usually, nested EPT), L2 is allowed to change its
|
|
|
|
* own CR3 without exiting. If it has changed it, we must keep it.
|
|
|
|
* Of course, if L0 is using shadow page tables, GUEST_CR3 was defined
|
|
|
|
* by L0, not L1 or L2, so we mustn't unconditionally copy it to vmcs12.
|
|
|
|
*
|
|
|
|
* Additionally, restore L2's PDPTR to vmcs12.
|
|
|
|
*/
|
|
|
|
if (enable_ept) {
|
|
|
|
vmcs12->guest_cr3 = vmcs_read64(GUEST_CR3);
|
|
|
|
vmcs12->guest_pdptr0 = vmcs_read64(GUEST_PDPTR0);
|
|
|
|
vmcs12->guest_pdptr1 = vmcs_read64(GUEST_PDPTR1);
|
|
|
|
vmcs12->guest_pdptr2 = vmcs_read64(GUEST_PDPTR2);
|
|
|
|
vmcs12->guest_pdptr3 = vmcs_read64(GUEST_PDPTR3);
|
|
|
|
}
|
|
|
|
|
2015-02-03 15:57:51 +00:00
|
|
|
if (nested_cpu_has_vid(vmcs12))
|
|
|
|
vmcs12->guest_intr_status = vmcs_read16(GUEST_INTR_STATUS);
|
|
|
|
|
2013-03-13 15:06:41 +00:00
|
|
|
vmcs12->vm_entry_controls =
|
|
|
|
(vmcs12->vm_entry_controls & ~VM_ENTRY_IA32E_MODE) |
|
2013-11-25 13:37:13 +00:00
|
|
|
(vm_entry_controls_get(to_vmx(vcpu)) & VM_ENTRY_IA32E_MODE);
|
2013-03-13 15:06:41 +00:00
|
|
|
|
2014-06-16 11:59:43 +00:00
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_DEBUG_CONTROLS) {
|
|
|
|
kvm_get_dr(vcpu, 7, (unsigned long *)&vmcs12->guest_dr7);
|
|
|
|
vmcs12->guest_ia32_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
/* TODO: These cannot have changed unless we have MSR bitmaps and
|
|
|
|
* the relevant bit asks not to trap the change */
|
2013-04-06 11:51:21 +00:00
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_PAT)
|
2011-05-25 20:11:34 +00:00
|
|
|
vmcs12->guest_ia32_pat = vmcs_read64(GUEST_IA32_PAT);
|
2013-08-08 14:26:31 +00:00
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
|
|
|
|
vmcs12->guest_ia32_efer = vcpu->arch.efer;
|
2011-05-25 20:11:34 +00:00
|
|
|
vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS);
|
|
|
|
vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
|
|
|
|
vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);
|
2014-02-24 11:30:04 +00:00
|
|
|
if (vmx_mpx_supported())
|
|
|
|
vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
|
2014-12-04 11:11:07 +00:00
|
|
|
if (nested_cpu_has_xsaves(vmcs12))
|
|
|
|
vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP);
|
2011-05-25 20:11:34 +00:00
|
|
|
|
|
|
|
/* update exit information fields: */
|
|
|
|
|
2014-01-04 17:47:20 +00:00
|
|
|
vmcs12->vm_exit_reason = exit_reason;
|
|
|
|
vmcs12->exit_qualification = exit_qualification;
|
2011-05-25 20:11:34 +00:00
|
|
|
|
2014-01-04 17:47:20 +00:00
|
|
|
vmcs12->vm_exit_intr_info = exit_intr_info;
|
2013-04-14 10:12:50 +00:00
|
|
|
if ((vmcs12->vm_exit_intr_info &
|
|
|
|
(INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) ==
|
|
|
|
(INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK))
|
|
|
|
vmcs12->vm_exit_intr_error_code =
|
|
|
|
vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
|
2013-04-14 10:12:46 +00:00
|
|
|
vmcs12->idt_vectoring_info_field = 0;
|
2011-05-25 20:11:34 +00:00
|
|
|
vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
|
|
|
|
vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
|
|
|
|
2013-04-14 10:12:46 +00:00
|
|
|
if (!(vmcs12->vm_exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY)) {
|
|
|
|
/* vm_entry_intr_info_field is cleared on exit. Emulate this
|
|
|
|
* instead of reading the real value. */
|
2011-05-25 20:11:34 +00:00
|
|
|
vmcs12->vm_entry_intr_info_field &= ~INTR_INFO_VALID_MASK;
|
2013-04-14 10:12:46 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Transfer the event that L0 or L1 may wanted to inject into
|
|
|
|
* L2 to IDT_VECTORING_INFO_FIELD.
|
|
|
|
*/
|
|
|
|
vmcs12_save_pending_event(vcpu, vmcs12);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Drop what we picked up for L2 via vmx_complete_interrupts. It is
|
|
|
|
* preserved above and would only end up incorrectly in L1.
|
|
|
|
*/
|
|
|
|
vcpu->arch.nmi_injected = false;
|
|
|
|
kvm_clear_exception_queue(vcpu);
|
|
|
|
kvm_clear_interrupt_queue(vcpu);
|
2011-05-25 20:11:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A part of what we need to when the nested L2 guest exits and we want to
|
|
|
|
* run its L1 parent, is to reset L1's guest state to the host state specified
|
|
|
|
* in vmcs12.
|
|
|
|
* This function is to be called not only on normal nested exit, but also on
|
|
|
|
* a nested entry failure, as explained in Intel's spec, 3B.23.7 ("VM-Entry
|
|
|
|
* Failures During or After Loading Guest State").
|
|
|
|
* This function should be called when the active VMCS is L1's (vmcs01).
|
|
|
|
*/
|
2013-02-23 14:07:47 +00:00
|
|
|
static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12)
|
2011-05-25 20:11:34 +00:00
|
|
|
{
|
2013-07-15 08:04:08 +00:00
|
|
|
struct kvm_segment seg;
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER)
|
|
|
|
vcpu->arch.efer = vmcs12->host_ia32_efer;
|
2013-04-14 10:44:54 +00:00
|
|
|
else if (vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE)
|
2011-05-25 20:11:34 +00:00
|
|
|
vcpu->arch.efer |= (EFER_LMA | EFER_LME);
|
|
|
|
else
|
|
|
|
vcpu->arch.efer &= ~(EFER_LMA | EFER_LME);
|
|
|
|
vmx_set_efer(vcpu, vcpu->arch.efer);
|
|
|
|
|
|
|
|
kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->host_rsp);
|
|
|
|
kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->host_rip);
|
2013-04-27 23:10:11 +00:00
|
|
|
vmx_set_rflags(vcpu, X86_EFLAGS_FIXED);
|
2011-05-25 20:11:34 +00:00
|
|
|
/*
|
|
|
|
* Note that calling vmx_set_cr0 is important, even if cr0 hasn't
|
|
|
|
* actually changed, because it depends on the current state of
|
|
|
|
* fpu_active (which may have changed).
|
|
|
|
* Note that vmx_set_cr0 refers to efer set above.
|
|
|
|
*/
|
2013-09-03 19:11:45 +00:00
|
|
|
vmx_set_cr0(vcpu, vmcs12->host_cr0);
|
2011-05-25 20:11:34 +00:00
|
|
|
/*
|
|
|
|
* If we did fpu_activate()/fpu_deactivate() during L2's run, we need
|
|
|
|
* to apply the same changes to L1's vmcs. We just set cr0 correctly,
|
|
|
|
* but we also need to update cr0_guest_host_mask and exception_bitmap.
|
|
|
|
*/
|
|
|
|
update_exception_bitmap(vcpu);
|
|
|
|
vcpu->arch.cr0_guest_owned_bits = (vcpu->fpu_active ? X86_CR0_TS : 0);
|
|
|
|
vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note that CR4_GUEST_HOST_MASK is already set in the original vmcs01
|
|
|
|
* (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask();
|
|
|
|
*/
|
|
|
|
vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK);
|
|
|
|
kvm_set_cr4(vcpu, vmcs12->host_cr4);
|
|
|
|
|
2013-12-28 15:31:52 +00:00
|
|
|
nested_ept_uninit_mmu_context(vcpu);
|
2013-08-05 08:07:16 +00:00
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
kvm_set_cr3(vcpu, vmcs12->host_cr3);
|
|
|
|
kvm_mmu_reset_context(vcpu);
|
|
|
|
|
2013-09-25 09:51:36 +00:00
|
|
|
if (!enable_ept)
|
|
|
|
vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault;
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
if (enable_vpid) {
|
|
|
|
/*
|
|
|
|
* Trivially support vpid by letting L2s share their parent
|
|
|
|
* L1's vpid. TODO: move to a more elaborate solution, giving
|
|
|
|
* each L2 its own vpid and exposing the vpid feature to L1.
|
|
|
|
*/
|
|
|
|
vmx_flush_tlb(vcpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vmcs_write32(GUEST_SYSENTER_CS, vmcs12->host_ia32_sysenter_cs);
|
|
|
|
vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->host_ia32_sysenter_esp);
|
|
|
|
vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->host_ia32_sysenter_eip);
|
|
|
|
vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base);
|
|
|
|
vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base);
|
|
|
|
|
2014-02-24 11:30:04 +00:00
|
|
|
/* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */
|
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS)
|
|
|
|
vmcs_write64(GUEST_BNDCFGS, 0);
|
|
|
|
|
2013-08-04 15:17:27 +00:00
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) {
|
2011-05-25 20:11:34 +00:00
|
|
|
vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat);
|
2013-08-04 15:17:27 +00:00
|
|
|
vcpu->arch.pat = vmcs12->host_ia32_pat;
|
|
|
|
}
|
2011-05-25 20:11:34 +00:00
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
|
|
|
|
vmcs_write64(GUEST_IA32_PERF_GLOBAL_CTRL,
|
|
|
|
vmcs12->host_ia32_perf_global_ctrl);
|
2013-03-03 12:05:44 +00:00
|
|
|
|
2013-07-15 08:04:08 +00:00
|
|
|
/* Set L1 segment info according to Intel SDM
|
|
|
|
27.5.2 Loading Host Segment and Descriptor-Table Registers */
|
|
|
|
seg = (struct kvm_segment) {
|
|
|
|
.base = 0,
|
|
|
|
.limit = 0xFFFFFFFF,
|
|
|
|
.selector = vmcs12->host_cs_selector,
|
|
|
|
.type = 11,
|
|
|
|
.present = 1,
|
|
|
|
.s = 1,
|
|
|
|
.g = 1
|
|
|
|
};
|
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE)
|
|
|
|
seg.l = 1;
|
|
|
|
else
|
|
|
|
seg.db = 1;
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_CS);
|
|
|
|
seg = (struct kvm_segment) {
|
|
|
|
.base = 0,
|
|
|
|
.limit = 0xFFFFFFFF,
|
|
|
|
.type = 3,
|
|
|
|
.present = 1,
|
|
|
|
.s = 1,
|
|
|
|
.db = 1,
|
|
|
|
.g = 1
|
|
|
|
};
|
|
|
|
seg.selector = vmcs12->host_ds_selector;
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_DS);
|
|
|
|
seg.selector = vmcs12->host_es_selector;
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_ES);
|
|
|
|
seg.selector = vmcs12->host_ss_selector;
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_SS);
|
|
|
|
seg.selector = vmcs12->host_fs_selector;
|
|
|
|
seg.base = vmcs12->host_fs_base;
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_FS);
|
|
|
|
seg.selector = vmcs12->host_gs_selector;
|
|
|
|
seg.base = vmcs12->host_gs_base;
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_GS);
|
|
|
|
seg = (struct kvm_segment) {
|
2013-08-04 12:08:06 +00:00
|
|
|
.base = vmcs12->host_tr_base,
|
2013-07-15 08:04:08 +00:00
|
|
|
.limit = 0x67,
|
|
|
|
.selector = vmcs12->host_tr_selector,
|
|
|
|
.type = 11,
|
|
|
|
.present = 1
|
|
|
|
};
|
|
|
|
vmx_set_segment(vcpu, &seg, VCPU_SREG_TR);
|
|
|
|
|
2013-03-03 12:05:44 +00:00
|
|
|
kvm_set_dr(vcpu, 7, 0x400);
|
|
|
|
vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
|
2014-12-11 05:52:58 +00:00
|
|
|
|
2015-02-03 15:49:31 +00:00
|
|
|
if (cpu_has_vmx_msr_bitmap())
|
|
|
|
vmx_set_msr_bitmap(vcpu);
|
|
|
|
|
2014-12-11 05:52:58 +00:00
|
|
|
if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr,
|
|
|
|
vmcs12->vm_exit_msr_load_count))
|
|
|
|
nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL);
|
2011-05-25 20:11:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Emulate an exit from nested guest (L2) to L1, i.e., prepare to run L1
|
|
|
|
* and modify vmcs12 to make it see what it would expect to see there if
|
|
|
|
* L2 was its real guest. Must only be called when in L2 (is_guest_mode())
|
|
|
|
*/
|
2014-01-04 17:47:20 +00:00
|
|
|
static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
|
|
|
|
u32 exit_intr_info,
|
|
|
|
unsigned long exit_qualification)
|
2011-05-25 20:11:34 +00:00
|
|
|
{
|
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
|
|
2013-04-14 10:12:46 +00:00
|
|
|
/* trying to cancel vmlaunch/vmresume is a bug */
|
|
|
|
WARN_ON_ONCE(vmx->nested.nested_run_pending);
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
leave_guest_mode(vcpu);
|
2014-01-04 17:47:20 +00:00
|
|
|
prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info,
|
|
|
|
exit_qualification);
|
2011-05-25 20:11:34 +00:00
|
|
|
|
2014-12-11 05:52:58 +00:00
|
|
|
if (nested_vmx_store_msr(vcpu, vmcs12->vm_exit_msr_store_addr,
|
|
|
|
vmcs12->vm_exit_msr_store_count))
|
|
|
|
nested_vmx_abort(vcpu, VMX_ABORT_SAVE_GUEST_MSR_FAIL);
|
|
|
|
|
2014-08-05 04:42:23 +00:00
|
|
|
vmx_load_vmcs01(vcpu);
|
|
|
|
|
2014-04-19 22:17:45 +00:00
|
|
|
if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT)
|
|
|
|
&& nested_exit_intr_ack_set(vcpu)) {
|
|
|
|
int irq = kvm_cpu_get_interrupt(vcpu);
|
|
|
|
WARN_ON(irq < 0);
|
|
|
|
vmcs12->vm_exit_intr_info = irq |
|
|
|
|
INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR;
|
|
|
|
}
|
|
|
|
|
2014-01-04 17:47:21 +00:00
|
|
|
trace_kvm_nested_vmexit_inject(vmcs12->vm_exit_reason,
|
|
|
|
vmcs12->exit_qualification,
|
|
|
|
vmcs12->idt_vectoring_info_field,
|
|
|
|
vmcs12->vm_exit_intr_info,
|
|
|
|
vmcs12->vm_exit_intr_error_code,
|
|
|
|
KVM_ISA_VMX);
|
2011-05-25 20:11:34 +00:00
|
|
|
|
2013-11-25 13:37:13 +00:00
|
|
|
vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS));
|
|
|
|
vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS));
|
2013-02-23 21:35:37 +00:00
|
|
|
vmx_segment_cache_clear(vmx);
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
/* if no vmcs02 cache requested, remove the one we used */
|
|
|
|
if (VMCS02_POOL_SIZE == 0)
|
|
|
|
nested_free_vmcs02(vmx, vmx->nested.current_vmptr);
|
|
|
|
|
|
|
|
load_vmcs12_host_state(vcpu, vmcs12);
|
|
|
|
|
2011-08-02 12:54:52 +00:00
|
|
|
/* Update TSC_OFFSET if TSC was changed while L2 ran */
|
2011-05-25 20:11:34 +00:00
|
|
|
vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
|
|
|
|
|
|
|
|
/* This is needed for same reason as it was needed in prepare_vmcs02 */
|
|
|
|
vmx->host_rsp = 0;
|
|
|
|
|
|
|
|
/* Unpin physical memory we referred to in vmcs02 */
|
|
|
|
if (vmx->nested.apic_access_page) {
|
|
|
|
nested_release_page(vmx->nested.apic_access_page);
|
2014-08-26 11:27:46 +00:00
|
|
|
vmx->nested.apic_access_page = NULL;
|
2011-05-25 20:11:34 +00:00
|
|
|
}
|
2014-08-21 11:46:50 +00:00
|
|
|
if (vmx->nested.virtual_apic_page) {
|
|
|
|
nested_release_page(vmx->nested.virtual_apic_page);
|
2014-08-26 11:27:46 +00:00
|
|
|
vmx->nested.virtual_apic_page = NULL;
|
2014-08-21 11:46:50 +00:00
|
|
|
}
|
2015-02-03 15:58:17 +00:00
|
|
|
if (vmx->nested.pi_desc_page) {
|
|
|
|
kunmap(vmx->nested.pi_desc_page);
|
|
|
|
nested_release_page(vmx->nested.pi_desc_page);
|
|
|
|
vmx->nested.pi_desc_page = NULL;
|
|
|
|
vmx->nested.pi_desc = NULL;
|
|
|
|
}
|
2011-05-25 20:11:34 +00:00
|
|
|
|
2014-09-24 07:57:54 +00:00
|
|
|
/*
|
|
|
|
* We are now running in L2, mmu_notifier will force to reload the
|
|
|
|
* page's hpa for L2 vmcs. Need to reload it for L1 before entering L1.
|
|
|
|
*/
|
|
|
|
kvm_vcpu_reload_apic_access_page(vcpu);
|
|
|
|
|
2011-05-25 20:11:34 +00:00
|
|
|
/*
|
|
|
|
* Exiting from L2 to L1, we're now back to L1 which thinks it just
|
|
|
|
* finished a VMLAUNCH or VMRESUME instruction, so we need to set the
|
|
|
|
* success or failure flag accordingly.
|
|
|
|
*/
|
|
|
|
if (unlikely(vmx->fail)) {
|
|
|
|
vmx->fail = 0;
|
|
|
|
nested_vmx_failValid(vcpu, vmcs_read32(VM_INSTRUCTION_ERROR));
|
|
|
|
} else
|
|
|
|
nested_vmx_succeed(vcpu);
|
2013-04-18 11:39:25 +00:00
|
|
|
if (enable_shadow_vmcs)
|
|
|
|
vmx->nested.sync_shadow_vmcs = true;
|
2014-03-07 19:03:12 +00:00
|
|
|
|
|
|
|
/* in case we halted in L2 */
|
|
|
|
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
|
2011-05-25 20:11:34 +00:00
|
|
|
}
|
|
|
|
|
2014-01-04 17:47:19 +00:00
|
|
|
/*
|
|
|
|
* Forcibly leave nested mode in order to be able to reset the VCPU later on.
|
|
|
|
*/
|
|
|
|
static void vmx_leave_nested(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
if (is_guest_mode(vcpu))
|
2014-01-04 17:47:20 +00:00
|
|
|
nested_vmx_vmexit(vcpu, -1, 0, 0);
|
2014-01-04 17:47:19 +00:00
|
|
|
free_nested(to_vmx(vcpu));
|
|
|
|
}
|
|
|
|
|
2011-05-25 20:12:04 +00:00
|
|
|
/*
|
|
|
|
* L1's failure to enter L2 is a subset of a normal exit, as explained in
|
|
|
|
* 23.7 "VM-entry failures during or after loading guest state" (this also
|
|
|
|
* lists the acceptable exit-reason and exit-qualification parameters).
|
|
|
|
* It should only be called before L2 actually succeeded to run, and when
|
|
|
|
* vmcs01 is current (it doesn't leave_guest_mode() or switch vmcss).
|
|
|
|
*/
|
|
|
|
static void nested_vmx_entry_failure(struct kvm_vcpu *vcpu,
|
|
|
|
struct vmcs12 *vmcs12,
|
|
|
|
u32 reason, unsigned long qualification)
|
|
|
|
{
|
|
|
|
load_vmcs12_host_state(vcpu, vmcs12);
|
|
|
|
vmcs12->vm_exit_reason = reason | VMX_EXIT_REASONS_FAILED_VMENTRY;
|
|
|
|
vmcs12->exit_qualification = qualification;
|
|
|
|
nested_vmx_succeed(vcpu);
|
2013-04-18 11:39:25 +00:00
|
|
|
if (enable_shadow_vmcs)
|
|
|
|
to_vmx(vcpu)->nested.sync_shadow_vmcs = true;
|
2011-05-25 20:12:04 +00:00
|
|
|
}
|
|
|
|
|
2011-04-04 10:39:27 +00:00
|
|
|
static int vmx_check_intercept(struct kvm_vcpu *vcpu,
|
|
|
|
struct x86_instruction_info *info,
|
|
|
|
enum x86_intercept_stage stage)
|
|
|
|
{
|
|
|
|
return X86EMUL_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2014-08-26 11:27:46 +00:00
|
|
|
static void vmx_sched_in(struct kvm_vcpu *vcpu, int cpu)
|
2014-08-21 16:08:06 +00:00
|
|
|
{
|
2014-08-21 16:08:08 +00:00
|
|
|
if (ple_gap)
|
|
|
|
shrink_ple_window(vcpu);
|
2014-08-21 16:08:06 +00:00
|
|
|
}
|
|
|
|
|
2015-01-28 02:54:28 +00:00
|
|
|
static void vmx_slot_enable_log_dirty(struct kvm *kvm,
|
|
|
|
struct kvm_memory_slot *slot)
|
|
|
|
{
|
|
|
|
kvm_mmu_slot_leaf_clear_dirty(kvm, slot);
|
|
|
|
kvm_mmu_slot_largepage_remove_write_access(kvm, slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_slot_disable_log_dirty(struct kvm *kvm,
|
|
|
|
struct kvm_memory_slot *slot)
|
|
|
|
{
|
|
|
|
kvm_mmu_slot_set_dirty(kvm, slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_flush_log_dirty(struct kvm *kvm)
|
|
|
|
{
|
|
|
|
kvm_flush_pml_buffers(kvm);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm,
|
|
|
|
struct kvm_memory_slot *memslot,
|
|
|
|
gfn_t offset, unsigned long mask)
|
|
|
|
{
|
|
|
|
kvm_mmu_clear_dirty_pt_masked(kvm, memslot, offset, mask);
|
|
|
|
}
|
|
|
|
|
2007-09-09 12:41:59 +00:00
|
|
|
static struct kvm_x86_ops vmx_x86_ops = {
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.cpu_has_kvm_support = cpu_has_kvm_support,
|
|
|
|
.disabled_by_bios = vmx_disabled_by_bios,
|
|
|
|
.hardware_setup = hardware_setup,
|
|
|
|
.hardware_unsetup = hardware_unsetup,
|
2007-07-31 11:23:01 +00:00
|
|
|
.check_processor_compatibility = vmx_check_processor_compat,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.hardware_enable = hardware_enable,
|
|
|
|
.hardware_disable = hardware_disable,
|
2009-04-01 07:52:31 +00:00
|
|
|
.cpu_has_accelerated_tpr = report_flexpriority,
|
2015-04-01 12:25:33 +00:00
|
|
|
.cpu_has_high_real_mode_segbase = vmx_has_high_real_mode_segbase,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
.vcpu_create = vmx_create_vcpu,
|
|
|
|
.vcpu_free = vmx_free_vcpu,
|
2007-09-10 15:10:54 +00:00
|
|
|
.vcpu_reset = vmx_vcpu_reset,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
2007-09-10 15:10:54 +00:00
|
|
|
.prepare_guest_switch = vmx_save_host_state,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.vcpu_load = vmx_vcpu_load,
|
|
|
|
.vcpu_put = vmx_vcpu_put,
|
|
|
|
|
2012-09-21 03:42:55 +00:00
|
|
|
.update_db_bp_intercept = update_exception_bitmap,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.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,
|
2008-03-24 17:38:34 +00:00
|
|
|
.get_cpl = vmx_get_cpl,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
|
2009-12-29 16:43:06 +00:00
|
|
|
.decache_cr0_guest_bits = vmx_decache_cr0_guest_bits,
|
2010-12-05 16:56:11 +00:00
|
|
|
.decache_cr3 = vmx_decache_cr3,
|
2007-04-27 06:29:21 +00:00
|
|
|
.decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.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,
|
|
|
|
.set_idt = vmx_set_idt,
|
|
|
|
.get_gdt = vmx_get_gdt,
|
|
|
|
.set_gdt = vmx_set_gdt,
|
2014-01-04 17:47:16 +00:00
|
|
|
.get_dr6 = vmx_get_dr6,
|
|
|
|
.set_dr6 = vmx_set_dr6,
|
2010-04-13 07:05:23 +00:00
|
|
|
.set_dr7 = vmx_set_dr7,
|
2014-02-21 09:32:27 +00:00
|
|
|
.sync_dirty_debug_regs = vmx_sync_dirty_debug_regs,
|
2008-06-27 17:58:02 +00:00
|
|
|
.cache_reg = vmx_cache_reg,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.get_rflags = vmx_get_rflags,
|
|
|
|
.set_rflags = vmx_set_rflags,
|
2015-05-20 09:33:43 +00:00
|
|
|
.fpu_activate = vmx_fpu_activate,
|
2009-12-30 10:40:26 +00:00
|
|
|
.fpu_deactivate = vmx_fpu_deactivate,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
|
|
|
|
.tlb_flush = vmx_flush_tlb,
|
|
|
|
|
|
|
|
.run = vmx_vcpu_run,
|
2009-03-23 15:35:17 +00:00
|
|
|
.handle_exit = vmx_handle_exit,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
.skip_emulated_instruction = skip_emulated_instruction,
|
2009-05-12 20:21:05 +00:00
|
|
|
.set_interrupt_shadow = vmx_set_interrupt_shadow,
|
|
|
|
.get_interrupt_shadow = vmx_get_interrupt_shadow,
|
2007-02-19 12:37:47 +00:00
|
|
|
.patch_hypercall = vmx_patch_hypercall,
|
2007-08-06 13:29:07 +00:00
|
|
|
.set_irq = vmx_inject_irq,
|
2009-04-21 14:45:08 +00:00
|
|
|
.set_nmi = vmx_inject_nmi,
|
2007-11-25 11:41:11 +00:00
|
|
|
.queue_exception = vmx_queue_exception,
|
2010-07-20 12:06:17 +00:00
|
|
|
.cancel_injection = vmx_cancel_injection,
|
2009-03-23 10:12:11 +00:00
|
|
|
.interrupt_allowed = vmx_interrupt_allowed,
|
2009-04-21 14:45:08 +00:00
|
|
|
.nmi_allowed = vmx_nmi_allowed,
|
2009-11-12 00:04:25 +00:00
|
|
|
.get_nmi_mask = vmx_get_nmi_mask,
|
|
|
|
.set_nmi_mask = vmx_set_nmi_mask,
|
2009-04-21 14:45:08 +00:00
|
|
|
.enable_nmi_window = enable_nmi_window,
|
|
|
|
.enable_irq_window = enable_irq_window,
|
|
|
|
.update_cr8_intercept = update_cr8_intercept,
|
2013-01-25 02:18:50 +00:00
|
|
|
.set_virtual_x2apic_mode = vmx_set_virtual_x2apic_mode,
|
2014-09-24 07:57:54 +00:00
|
|
|
.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
|
2015-07-29 09:49:59 +00:00
|
|
|
.cpu_uses_apicv = vmx_cpu_uses_apicv,
|
2013-01-25 02:18:51 +00:00
|
|
|
.load_eoi_exitmap = vmx_load_eoi_exitmap,
|
|
|
|
.hwapic_irr_update = vmx_hwapic_irr_update,
|
|
|
|
.hwapic_isr_update = vmx_hwapic_isr_update,
|
2013-04-11 11:25:15 +00:00
|
|
|
.sync_pir_to_irr = vmx_sync_pir_to_irr,
|
|
|
|
.deliver_posted_interrupt = vmx_deliver_posted_interrupt,
|
2009-04-21 14:45:08 +00:00
|
|
|
|
2007-10-24 22:29:55 +00:00
|
|
|
.set_tss_addr = vmx_set_tss_addr,
|
2008-04-25 02:20:22 +00:00
|
|
|
.get_tdp_level = get_ept_level,
|
2009-04-27 12:35:42 +00:00
|
|
|
.get_mt_mask = vmx_get_mt_mask,
|
2009-06-17 12:22:14 +00:00
|
|
|
|
2010-11-18 11:09:54 +00:00
|
|
|
.get_exit_info = vmx_get_exit_info,
|
|
|
|
|
2010-01-05 11:02:27 +00:00
|
|
|
.get_lpage_level = vmx_get_lpage_level,
|
2009-12-18 08:48:46 +00:00
|
|
|
|
|
|
|
.cpuid_update = vmx_cpuid_update,
|
2009-12-18 08:48:47 +00:00
|
|
|
|
|
|
|
.rdtscp_supported = vmx_rdtscp_supported,
|
2012-07-02 01:18:48 +00:00
|
|
|
.invpcid_supported = vmx_invpcid_supported,
|
2010-04-22 10:33:11 +00:00
|
|
|
|
|
|
|
.set_supported_cpuid = vmx_set_supported_cpuid,
|
2010-06-30 04:25:15 +00:00
|
|
|
|
|
|
|
.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
|
2010-08-20 08:07:17 +00:00
|
|
|
|
2011-03-25 08:44:49 +00:00
|
|
|
.set_tsc_khz = vmx_set_tsc_khz,
|
2012-11-29 20:42:50 +00:00
|
|
|
.read_tsc_offset = vmx_read_tsc_offset,
|
2010-08-20 08:07:17 +00:00
|
|
|
.write_tsc_offset = vmx_write_tsc_offset,
|
2010-08-20 08:07:23 +00:00
|
|
|
.adjust_tsc_offset = vmx_adjust_tsc_offset,
|
2011-03-25 08:44:50 +00:00
|
|
|
.compute_tsc_offset = vmx_compute_tsc_offset,
|
2011-08-02 12:54:20 +00:00
|
|
|
.read_l1_tsc = vmx_read_l1_tsc,
|
2010-09-10 15:30:41 +00:00
|
|
|
|
|
|
|
.set_tdp_cr3 = vmx_set_cr3,
|
2011-04-04 10:39:27 +00:00
|
|
|
|
|
|
|
.check_intercept = vmx_check_intercept,
|
2013-04-11 11:25:10 +00:00
|
|
|
.handle_external_intr = vmx_handle_external_intr,
|
2014-02-24 10:55:46 +00:00
|
|
|
.mpx_supported = vmx_mpx_supported,
|
2014-12-02 11:21:30 +00:00
|
|
|
.xsaves_supported = vmx_xsaves_supported,
|
2014-03-07 19:03:12 +00:00
|
|
|
|
|
|
|
.check_nested_events = vmx_check_nested_events,
|
2014-08-21 16:08:06 +00:00
|
|
|
|
|
|
|
.sched_in = vmx_sched_in,
|
2015-01-28 02:54:28 +00:00
|
|
|
|
|
|
|
.slot_enable_log_dirty = vmx_slot_enable_log_dirty,
|
|
|
|
.slot_disable_log_dirty = vmx_slot_disable_log_dirty,
|
|
|
|
.flush_log_dirty = vmx_flush_log_dirty,
|
|
|
|
.enable_log_dirty_pt_masked = vmx_enable_log_dirty_pt_masked,
|
2015-06-19 13:45:05 +00:00
|
|
|
|
|
|
|
.pmu_ops = &intel_pmu_ops,
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static int __init vmx_init(void)
|
|
|
|
{
|
2014-10-28 02:14:48 +00:00
|
|
|
int r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx),
|
|
|
|
__alignof__(struct vcpu_vmx), THIS_MODULE);
|
2007-04-30 06:45:24 +00:00
|
|
|
if (r)
|
2014-10-28 02:14:48 +00:00
|
|
|
return r;
|
2008-03-28 05:18:56 +00:00
|
|
|
|
2015-09-09 22:38:55 +00:00
|
|
|
#ifdef CONFIG_KEXEC_CORE
|
2012-12-06 15:43:34 +00:00
|
|
|
rcu_assign_pointer(crash_vmclear_loaded_vmcss,
|
|
|
|
crash_vmclear_local_loaded_vmcss);
|
|
|
|
#endif
|
|
|
|
|
2007-04-30 06:45:24 +00:00
|
|
|
return 0;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit vmx_exit(void)
|
|
|
|
{
|
2015-09-09 22:38:55 +00:00
|
|
|
#ifdef CONFIG_KEXEC_CORE
|
2014-03-22 06:58:10 +00:00
|
|
|
RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL);
|
2012-12-06 15:43:34 +00:00
|
|
|
synchronize_rcu();
|
|
|
|
#endif
|
|
|
|
|
2007-11-14 12:39:31 +00:00
|
|
|
kvm_exit();
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 10:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module_init(vmx_init)
|
|
|
|
module_exit(vmx_exit)
|