2007-12-16 16:02:48 +07:00
|
|
|
#ifndef __KVM_HOST_H
|
|
|
|
#define __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 17:21:36 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
|
|
* the COPYING file in the top-level directory.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
2007-10-18 19:39:10 +07:00
|
|
|
#include <linux/hardirq.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 17:21:36 +07:00
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
#include <linux/spinlock.h>
|
2007-05-27 14:46:52 +07:00
|
|
|
#include <linux/signal.h>
|
|
|
|
#include <linux/sched.h>
|
2011-11-24 08:12:59 +07:00
|
|
|
#include <linux/bug.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 17:21:36 +07:00
|
|
|
#include <linux/mm.h>
|
2011-10-10 22:46:15 +07:00
|
|
|
#include <linux/mmu_notifier.h>
|
2007-07-11 22:17:21 +07:00
|
|
|
#include <linux/preempt.h>
|
2008-11-24 13:32:53 +07:00
|
|
|
#include <linux/msi.h>
|
2010-11-09 23:02:49 +07:00
|
|
|
#include <linux/slab.h>
|
2010-11-19 00:09:08 +07:00
|
|
|
#include <linux/rcupdate.h>
|
2011-09-12 16:26:22 +07:00
|
|
|
#include <linux/ratelimit.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-21 04:22:52 +07:00
|
|
|
#include <asm/signal.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 17:21:36 +07:00
|
|
|
|
|
|
|
#include <linux/kvm.h>
|
2007-02-19 19:37:47 +07:00
|
|
|
#include <linux/kvm_para.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 17:21:36 +07:00
|
|
|
|
2007-12-16 16:02:48 +07:00
|
|
|
#include <linux/kvm_types.h>
|
2007-12-04 04:30:23 +07:00
|
|
|
|
2007-12-16 16:02:48 +07:00
|
|
|
#include <asm/kvm_host.h>
|
2007-12-14 08:41:22 +07:00
|
|
|
|
2010-01-20 17:01:20 +07:00
|
|
|
#ifndef KVM_MMIO_SIZE
|
|
|
|
#define KVM_MMIO_SIZE 8
|
|
|
|
#endif
|
|
|
|
|
2012-04-18 23:22:47 +07:00
|
|
|
/*
|
|
|
|
* If we support unaligned MMIO, at most one fragment will be split into two:
|
|
|
|
*/
|
|
|
|
#ifdef KVM_UNALIGNED_MMIO
|
|
|
|
# define KVM_EXTRA_MMIO_FRAGMENTS 1
|
|
|
|
#else
|
|
|
|
# define KVM_EXTRA_MMIO_FRAGMENTS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define KVM_USER_MMIO_SIZE 8
|
|
|
|
|
|
|
|
#define KVM_MAX_MMIO_FRAGMENTS \
|
|
|
|
(KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS)
|
|
|
|
|
2012-08-03 14:37:54 +07:00
|
|
|
#define KVM_PFN_ERR_FAULT (-EFAULT)
|
2012-08-03 14:38:36 +07:00
|
|
|
#define KVM_PFN_ERR_HWPOISON (-EHWPOISON)
|
2012-08-03 14:39:19 +07:00
|
|
|
#define KVM_PFN_ERR_BAD (-ENOENT)
|
2012-08-03 14:37:54 +07:00
|
|
|
|
2007-06-07 23:18:30 +07:00
|
|
|
/*
|
|
|
|
* vcpu->requests bit members
|
|
|
|
*/
|
2007-10-16 22:22:08 +07:00
|
|
|
#define KVM_REQ_TLB_FLUSH 0
|
2008-01-16 17:49:30 +07:00
|
|
|
#define KVM_REQ_MIGRATE_TIMER 1
|
2007-10-22 21:50:39 +07:00
|
|
|
#define KVM_REQ_REPORT_TPR_ACCESS 2
|
2008-02-21 02:47:24 +07:00
|
|
|
#define KVM_REQ_MMU_RELOAD 3
|
2008-02-26 22:49:16 +07:00
|
|
|
#define KVM_REQ_TRIPLE_FAULT 4
|
2008-06-07 02:37:36 +07:00
|
|
|
#define KVM_REQ_PENDING_TIMER 5
|
2008-09-09 01:23:48 +07:00
|
|
|
#define KVM_REQ_UNHALT 6
|
2008-09-23 23:18:39 +07:00
|
|
|
#define KVM_REQ_MMU_SYNC 7
|
2010-09-19 07:38:14 +07:00
|
|
|
#define KVM_REQ_CLOCK_UPDATE 8
|
2009-05-08 03:55:12 +07:00
|
|
|
#define KVM_REQ_KICK 9
|
2009-12-30 17:40:26 +07:00
|
|
|
#define KVM_REQ_DEACTIVATE_FPU 10
|
2010-07-27 16:30:24 +07:00
|
|
|
#define KVM_REQ_EVENT 11
|
2010-10-14 16:22:46 +07:00
|
|
|
#define KVM_REQ_APF_HALT 12
|
2011-07-12 02:28:14 +07:00
|
|
|
#define KVM_REQ_STEAL_UPDATE 13
|
2011-09-20 17:43:14 +07:00
|
|
|
#define KVM_REQ_NMI 14
|
KVM: nVMX: Add KVM_REQ_IMMEDIATE_EXIT
This patch adds a new vcpu->requests bit, KVM_REQ_IMMEDIATE_EXIT.
This bit requests that when next entering the guest, we should run it only
for as little as possible, and exit again.
We use this new option in nested VMX: When L1 launches L2, but L0 wishes L1
to continue running so it can inject an event to it, we unfortunately cannot
just pretend to have run L2 for a little while - We must really launch L2,
otherwise certain one-off vmcs12 parameters (namely, L1 injection into L2)
will be lost. So the existing code runs L2 in this case.
But L2 could potentially run for a long time until it exits, and the
injection into L1 will be delayed. The new KVM_REQ_IMMEDIATE_EXIT allows us
to request that L2 will be entered, as necessary, but will exit as soon as
possible after entry.
Our implementation of this request uses smp_send_reschedule() to send a
self-IPI, with interrupts disabled. The interrupts remain disabled until the
guest is entered, and then, after the entry is complete (often including
processing an injection and jumping to the relevant handler), the physical
interrupt is noticed and causes an exit.
On recent Intel processors, we could have achieved the same goal by using
MTF instead of a self-IPI. Another technique worth considering in the future
is to use VM_EXIT_ACK_INTR_ON_EXIT and a highest-priority vector IPI - to
slightly improve performance by avoiding the useless interrupt handler
which ends up being called when smp_send_reschedule() is used.
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-09-22 17:52:56 +07:00
|
|
|
#define KVM_REQ_IMMEDIATE_EXIT 15
|
2011-11-10 19:57:22 +07:00
|
|
|
#define KVM_REQ_PMU 16
|
|
|
|
#define KVM_REQ_PMI 17
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
|
2008-10-15 19:15:06 +07:00
|
|
|
#define KVM_USERSPACE_IRQ_SOURCE_ID 0
|
|
|
|
|
2009-06-30 02:24:26 +07:00
|
|
|
struct 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 17:21:36 +07:00
|
|
|
struct kvm_vcpu;
|
2007-07-30 18:12:19 +07:00
|
|
|
extern struct kmem_cache *kvm_vcpu_cache;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
|
2011-07-27 20:00:48 +07:00
|
|
|
struct kvm_io_range {
|
|
|
|
gpa_t addr;
|
|
|
|
int len;
|
|
|
|
struct kvm_io_device *dev;
|
|
|
|
};
|
|
|
|
|
2012-03-09 11:17:40 +07:00
|
|
|
#define NR_IOBUS_DEVS 1000
|
2012-03-09 11:17:32 +07:00
|
|
|
|
2007-06-01 01:08:53 +07:00
|
|
|
struct kvm_io_bus {
|
|
|
|
int dev_count;
|
2012-03-09 11:17:32 +07:00
|
|
|
struct kvm_io_range range[];
|
2007-06-01 01:08:53 +07:00
|
|
|
};
|
|
|
|
|
2009-12-23 23:35:24 +07:00
|
|
|
enum kvm_bus {
|
|
|
|
KVM_MMIO_BUS,
|
|
|
|
KVM_PIO_BUS,
|
|
|
|
KVM_NR_BUSES
|
|
|
|
};
|
|
|
|
|
|
|
|
int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
|
|
|
|
int len, const void *val);
|
|
|
|
int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len,
|
2009-06-30 02:24:32 +07:00
|
|
|
void *val);
|
2011-07-27 20:00:48 +07:00
|
|
|
int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
|
|
|
|
int len, struct kvm_io_device *dev);
|
2009-12-23 23:35:24 +07:00
|
|
|
int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
|
|
|
|
struct kvm_io_device *dev);
|
2007-06-01 01:08:53 +07:00
|
|
|
|
2010-10-14 16:22:46 +07:00
|
|
|
#ifdef CONFIG_KVM_ASYNC_PF
|
|
|
|
struct kvm_async_pf {
|
|
|
|
struct work_struct work;
|
|
|
|
struct list_head link;
|
|
|
|
struct list_head queue;
|
|
|
|
struct kvm_vcpu *vcpu;
|
|
|
|
struct mm_struct *mm;
|
|
|
|
gva_t gva;
|
|
|
|
unsigned long addr;
|
|
|
|
struct kvm_arch_async_pf arch;
|
|
|
|
struct page *page;
|
|
|
|
bool done;
|
|
|
|
};
|
|
|
|
|
|
|
|
void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu);
|
|
|
|
void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu);
|
|
|
|
int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
|
|
|
|
struct kvm_arch_async_pf *arch);
|
2010-10-14 16:22:50 +07:00
|
|
|
int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu);
|
2010-10-14 16:22:46 +07:00
|
|
|
#endif
|
|
|
|
|
2011-01-12 14:40:31 +07:00
|
|
|
enum {
|
|
|
|
OUTSIDE_GUEST_MODE,
|
|
|
|
IN_GUEST_MODE,
|
2012-05-14 19:44:06 +07:00
|
|
|
EXITING_GUEST_MODE,
|
|
|
|
READING_SHADOW_PAGE_TABLES,
|
2011-01-12 14:40:31 +07:00
|
|
|
};
|
|
|
|
|
2012-04-18 23:22:47 +07:00
|
|
|
/*
|
|
|
|
* Sometimes a large or cross-page mmio needs to be broken up into separate
|
|
|
|
* exits for userspace servicing.
|
|
|
|
*/
|
|
|
|
struct kvm_mmio_fragment {
|
|
|
|
gpa_t gpa;
|
|
|
|
void *data;
|
|
|
|
unsigned len;
|
|
|
|
};
|
|
|
|
|
2007-12-14 08:45:31 +07:00
|
|
|
struct kvm_vcpu {
|
|
|
|
struct kvm *kvm;
|
2008-01-29 06:42:34 +07:00
|
|
|
#ifdef CONFIG_PREEMPT_NOTIFIERS
|
2007-12-14 08:45:31 +07:00
|
|
|
struct preempt_notifier preempt_notifier;
|
2008-01-29 06:42:34 +07:00
|
|
|
#endif
|
2011-01-12 14:40:31 +07:00
|
|
|
int cpu;
|
2007-12-14 08:45:31 +07:00
|
|
|
int vcpu_id;
|
2011-01-12 14:40:31 +07:00
|
|
|
int srcu_idx;
|
|
|
|
int mode;
|
2007-12-14 08:45:31 +07:00
|
|
|
unsigned long requests;
|
2008-12-15 19:52:10 +07:00
|
|
|
unsigned long guest_debug;
|
2011-01-12 14:40:31 +07:00
|
|
|
|
|
|
|
struct mutex mutex;
|
|
|
|
struct kvm_run *run;
|
2009-12-23 23:35:25 +07:00
|
|
|
|
2007-12-14 08:45:31 +07:00
|
|
|
int fpu_active;
|
2010-06-10 10:27:12 +07:00
|
|
|
int guest_fpu_loaded, guest_xcr0_loaded;
|
2007-12-14 08:45:31 +07:00
|
|
|
wait_queue_head_t wq;
|
2011-02-01 21:52:41 +07:00
|
|
|
struct pid *pid;
|
2007-12-14 08:45:31 +07:00
|
|
|
int sigset_active;
|
|
|
|
sigset_t sigset;
|
|
|
|
struct kvm_vcpu_stat stat;
|
|
|
|
|
2007-10-20 14:34:38 +07:00
|
|
|
#ifdef CONFIG_HAS_IOMEM
|
2007-12-14 08:45:31 +07:00
|
|
|
int mmio_needed;
|
|
|
|
int mmio_read_completed;
|
|
|
|
int mmio_is_write;
|
2012-04-18 23:22:47 +07:00
|
|
|
int mmio_cur_fragment;
|
|
|
|
int mmio_nr_fragments;
|
|
|
|
struct kvm_mmio_fragment mmio_fragments[KVM_MAX_MMIO_FRAGMENTS];
|
2007-10-20 14:34:38 +07:00
|
|
|
#endif
|
2007-04-19 21:27:43 +07:00
|
|
|
|
2010-10-14 16:22:46 +07:00
|
|
|
#ifdef CONFIG_KVM_ASYNC_PF
|
|
|
|
struct {
|
|
|
|
u32 queued;
|
|
|
|
struct list_head queue;
|
|
|
|
struct list_head done;
|
|
|
|
spinlock_t lock;
|
|
|
|
} async_pf;
|
|
|
|
#endif
|
|
|
|
|
2012-07-18 20:37:46 +07:00
|
|
|
#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
|
|
|
|
/*
|
|
|
|
* Cpu relax intercept or pause loop exit optimization
|
|
|
|
* in_spin_loop: set when a vcpu does a pause loop exit
|
|
|
|
* or cpu relax intercepted.
|
|
|
|
* dy_eligible: indicates whether vcpu is eligible for directed yield.
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
bool in_spin_loop;
|
|
|
|
bool dy_eligible;
|
|
|
|
} spin_loop;
|
|
|
|
#endif
|
2007-12-14 08:41:22 +07:00
|
|
|
struct kvm_vcpu_arch arch;
|
|
|
|
};
|
|
|
|
|
2011-01-12 14:40:31 +07:00
|
|
|
static inline int kvm_vcpu_exiting_guest_mode(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return cmpxchg(&vcpu->mode, IN_GUEST_MODE, EXITING_GUEST_MODE);
|
|
|
|
}
|
|
|
|
|
2010-04-13 20:47:24 +07:00
|
|
|
/*
|
|
|
|
* Some of the bitops functions do not support too long bitmaps.
|
|
|
|
* This number must be determined not to exceed such limits.
|
|
|
|
*/
|
|
|
|
#define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 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 17:21:36 +07:00
|
|
|
struct kvm_memory_slot {
|
|
|
|
gfn_t base_gfn;
|
|
|
|
unsigned long npages;
|
|
|
|
unsigned long flags;
|
|
|
|
unsigned long *dirty_bitmap;
|
2012-02-08 11:02:18 +07:00
|
|
|
struct kvm_arch_memory_slot arch;
|
2007-10-18 16:09:33 +07:00
|
|
|
unsigned long userspace_addr;
|
2007-10-25 16:54:04 +07:00
|
|
|
int user_alloc;
|
2010-06-21 14:56:36 +07:00
|
|
|
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 17:21:36 +07:00
|
|
|
};
|
|
|
|
|
2010-04-12 17:35:35 +07:00
|
|
|
static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
|
|
|
|
{
|
|
|
|
return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
|
|
|
|
}
|
|
|
|
|
2008-11-19 18:58:46 +07:00
|
|
|
struct kvm_kernel_irq_routing_entry {
|
|
|
|
u32 gsi;
|
2009-07-26 21:10:01 +07:00
|
|
|
u32 type;
|
2009-02-04 22:28:14 +07:00
|
|
|
int (*set)(struct kvm_kernel_irq_routing_entry *e,
|
2009-08-24 15:54:19 +07:00
|
|
|
struct kvm *kvm, int irq_source_id, int level);
|
2008-11-19 18:58:46 +07:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
unsigned irqchip;
|
|
|
|
unsigned pin;
|
|
|
|
} irqchip;
|
2009-02-10 12:57:06 +07:00
|
|
|
struct msi_msg msi;
|
2008-11-19 18:58:46 +07:00
|
|
|
};
|
2009-08-24 15:54:20 +07:00
|
|
|
struct hlist_node link;
|
|
|
|
};
|
|
|
|
|
2009-08-24 15:54:21 +07:00
|
|
|
#ifdef __KVM_HAVE_IOAPIC
|
|
|
|
|
2009-08-24 15:54:20 +07:00
|
|
|
struct kvm_irq_routing_table {
|
2009-08-24 15:54:21 +07:00
|
|
|
int chip[KVM_NR_IRQCHIPS][KVM_IOAPIC_NUM_PINS];
|
2009-08-24 15:54:20 +07:00
|
|
|
struct kvm_kernel_irq_routing_entry *rt_entries;
|
|
|
|
u32 nr_rt_entries;
|
|
|
|
/*
|
|
|
|
* Array indexed by gsi. Each entry contains list of irq chips
|
|
|
|
* the gsi is connected to.
|
|
|
|
*/
|
|
|
|
struct hlist_head map[0];
|
2008-11-19 18:58:46 +07:00
|
|
|
};
|
|
|
|
|
2009-08-24 15:54:21 +07:00
|
|
|
#else
|
|
|
|
|
|
|
|
struct kvm_irq_routing_table {};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2011-11-24 16:37:48 +07:00
|
|
|
#ifndef KVM_MEM_SLOTS_NUM
|
|
|
|
#define KVM_MEM_SLOTS_NUM (KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS)
|
|
|
|
#endif
|
|
|
|
|
2011-11-24 16:40:57 +07:00
|
|
|
/*
|
|
|
|
* Note:
|
|
|
|
* memslots are not sorted by id anymore, please use id_to_memslot()
|
|
|
|
* to get the memslot by its id.
|
|
|
|
*/
|
2009-12-23 23:35:16 +07:00
|
|
|
struct kvm_memslots {
|
2010-10-18 20:22:23 +07:00
|
|
|
u64 generation;
|
2011-11-24 16:37:48 +07:00
|
|
|
struct kvm_memory_slot memslots[KVM_MEM_SLOTS_NUM];
|
2011-11-24 16:41:54 +07:00
|
|
|
/* The mapping table from slot id to the index in memslots[]. */
|
|
|
|
int id_to_index[KVM_MEM_SLOTS_NUM];
|
2009-12-23 23:35:16 +07: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 17:21:36 +07:00
|
|
|
struct kvm {
|
2007-12-21 07:18:26 +07:00
|
|
|
spinlock_t mmu_lock;
|
2009-12-23 23:35:26 +07:00
|
|
|
struct mutex slots_lock;
|
2007-11-21 21:41:05 +07:00
|
|
|
struct mm_struct *mm; /* userspace tied to this vm */
|
2009-12-23 23:35:16 +07:00
|
|
|
struct kvm_memslots *memslots;
|
2009-12-23 23:35:21 +07:00
|
|
|
struct srcu_struct srcu;
|
2009-06-09 19:56:28 +07:00
|
|
|
#ifdef CONFIG_KVM_APIC_ARCHITECTURE
|
|
|
|
u32 bsp_vcpu_id;
|
|
|
|
#endif
|
2007-07-27 14:16:56 +07:00
|
|
|
struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
|
2009-06-09 19:56:28 +07:00
|
|
|
atomic_t online_vcpus;
|
2011-02-01 21:53:28 +07:00
|
|
|
int last_boosted_vcpu;
|
2007-02-12 15:54:44 +07:00
|
|
|
struct list_head vm_list;
|
2009-06-05 01:08:23 +07:00
|
|
|
struct mutex lock;
|
2009-12-23 23:35:24 +07:00
|
|
|
struct kvm_io_bus *buses[KVM_NR_BUSES];
|
2009-05-20 21:30:49 +07:00
|
|
|
#ifdef CONFIG_HAVE_KVM_EVENTFD
|
|
|
|
struct {
|
|
|
|
spinlock_t lock;
|
|
|
|
struct list_head items;
|
|
|
|
} irqfds;
|
KVM: add ioeventfd support
ioeventfd is a mechanism to register PIO/MMIO regions to trigger an eventfd
signal when written to by a guest. Host userspace can register any
arbitrary IO address with a corresponding eventfd and then pass the eventfd
to a specific end-point of interest for handling.
Normal IO requires a blocking round-trip since the operation may cause
side-effects in the emulated model or may return data to the caller.
Therefore, an IO in KVM traps from the guest to the host, causes a VMX/SVM
"heavy-weight" exit back to userspace, and is ultimately serviced by qemu's
device model synchronously before returning control back to the vcpu.
However, there is a subclass of IO which acts purely as a trigger for
other IO (such as to kick off an out-of-band DMA request, etc). For these
patterns, the synchronous call is particularly expensive since we really
only want to simply get our notification transmitted asychronously and
return as quickly as possible. All the sychronous infrastructure to ensure
proper data-dependencies are met in the normal IO case are just unecessary
overhead for signalling. This adds additional computational load on the
system, as well as latency to the signalling path.
Therefore, we provide a mechanism for registration of an in-kernel trigger
point that allows the VCPU to only require a very brief, lightweight
exit just long enough to signal an eventfd. This also means that any
clients compatible with the eventfd interface (which includes userspace
and kernelspace equally well) can now register to be notified. The end
result should be a more flexible and higher performance notification API
for the backend KVM hypervisor and perhipheral components.
To test this theory, we built a test-harness called "doorbell". This
module has a function called "doorbell_ring()" which simply increments a
counter for each time the doorbell is signaled. It supports signalling
from either an eventfd, or an ioctl().
We then wired up two paths to the doorbell: One via QEMU via a registered
io region and through the doorbell ioctl(). The other is direct via
ioeventfd.
You can download this test harness here:
ftp://ftp.novell.com/dev/ghaskins/doorbell.tar.bz2
The measured results are as follows:
qemu-mmio: 110000 iops, 9.09us rtt
ioeventfd-mmio: 200100 iops, 5.00us rtt
ioeventfd-pio: 367300 iops, 2.72us rtt
I didn't measure qemu-pio, because I have to figure out how to register a
PIO region with qemu's device model, and I got lazy. However, for now we
can extrapolate based on the data from the NULLIO runs of +2.56us for MMIO,
and -350ns for HC, we get:
qemu-pio: 153139 iops, 6.53us rtt
ioeventfd-hc: 412585 iops, 2.37us rtt
these are just for fun, for now, until I can gather more data.
Here is a graph for your convenience:
http://developer.novell.com/wiki/images/7/76/Iofd-chart.png
The conclusion to draw is that we save about 4us by skipping the userspace
hop.
--------------------
Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2009-07-08 04:08:49 +07:00
|
|
|
struct list_head ioeventfds;
|
2009-05-20 21:30:49 +07:00
|
|
|
#endif
|
2007-11-18 21:24:12 +07:00
|
|
|
struct kvm_vm_stat stat;
|
2007-12-14 08:54:20 +07:00
|
|
|
struct kvm_arch arch;
|
2008-03-30 20:01:25 +07:00
|
|
|
atomic_t users_count;
|
2008-05-30 21:05:54 +07:00
|
|
|
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
|
|
|
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
|
2011-07-21 00:59:00 +07:00
|
|
|
spinlock_t ring_lock;
|
|
|
|
struct list_head coalesced_zones;
|
2008-05-30 21:05:54 +07:00
|
|
|
#endif
|
2008-07-25 21:24:52 +07:00
|
|
|
|
2009-06-05 01:08:23 +07:00
|
|
|
struct mutex irq_lock;
|
2009-01-04 22:10:50 +07:00
|
|
|
#ifdef CONFIG_HAVE_KVM_IRQCHIP
|
2010-11-19 00:09:08 +07:00
|
|
|
/*
|
|
|
|
* Update side is protected by irq_lock and,
|
|
|
|
* if configured, irqfds.lock.
|
|
|
|
*/
|
2010-03-04 21:59:23 +07:00
|
|
|
struct kvm_irq_routing_table __rcu *irq_routing;
|
2009-01-04 22:10:50 +07:00
|
|
|
struct hlist_head mask_notifier_list;
|
2009-08-24 15:54:23 +07:00
|
|
|
struct hlist_head irq_ack_notifier_list;
|
2009-01-04 22:10:50 +07:00
|
|
|
#endif
|
|
|
|
|
2012-06-16 02:07:24 +07:00
|
|
|
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
|
2008-07-25 21:24:52 +07:00
|
|
|
struct mmu_notifier mmu_notifier;
|
|
|
|
unsigned long mmu_notifier_seq;
|
|
|
|
long mmu_notifier_count;
|
|
|
|
#endif
|
2010-12-08 23:04:51 +07:00
|
|
|
long tlbs_dirty;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
};
|
|
|
|
|
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-04 01:17:48 +07:00
|
|
|
#define kvm_err(fmt, ...) \
|
|
|
|
pr_err("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
|
|
|
|
#define kvm_info(fmt, ...) \
|
|
|
|
pr_info("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
|
|
|
|
#define kvm_debug(fmt, ...) \
|
|
|
|
pr_debug("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
|
|
|
|
#define kvm_pr_unimpl(fmt, ...) \
|
|
|
|
pr_err_ratelimited("kvm [%i]: " fmt, \
|
|
|
|
task_tgid_nr(current), ## __VA_ARGS__)
|
2007-08-01 07:48:02 +07:00
|
|
|
|
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-04 01:17:48 +07:00
|
|
|
/* The guest did something we don't support. */
|
|
|
|
#define vcpu_unimpl(vcpu, fmt, ...) \
|
|
|
|
kvm_pr_unimpl("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
|
2009-06-09 19:56:29 +07:00
|
|
|
static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
|
|
|
|
{
|
|
|
|
smp_rmb();
|
|
|
|
return kvm->vcpus[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
#define kvm_for_each_vcpu(idx, vcpup, kvm) \
|
2011-04-13 08:30:17 +07:00
|
|
|
for (idx = 0; \
|
|
|
|
idx < atomic_read(&kvm->online_vcpus) && \
|
|
|
|
(vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \
|
|
|
|
idx++)
|
2009-06-09 19:56:29 +07:00
|
|
|
|
2011-11-24 16:39:18 +07:00
|
|
|
#define kvm_for_each_memslot(memslot, slots) \
|
|
|
|
for (memslot = &slots->memslots[0]; \
|
2011-11-24 16:40:57 +07:00
|
|
|
memslot < slots->memslots + KVM_MEM_SLOTS_NUM && memslot->npages;\
|
|
|
|
memslot++)
|
2011-11-24 16:39:18 +07:00
|
|
|
|
2007-07-27 14:16:56 +07:00
|
|
|
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id);
|
|
|
|
void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
|
|
|
|
|
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-12 00:16:52 +07:00
|
|
|
void vcpu_load(struct kvm_vcpu *vcpu);
|
|
|
|
void vcpu_put(struct kvm_vcpu *vcpu);
|
|
|
|
|
2010-04-28 19:39:01 +07:00
|
|
|
int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
|
2007-07-30 18:12:19 +07:00
|
|
|
struct module *module);
|
2007-11-14 19:39:31 +07:00
|
|
|
void kvm_exit(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 17:21:36 +07:00
|
|
|
|
2008-03-30 20:01:25 +07:00
|
|
|
void kvm_get_kvm(struct kvm *kvm);
|
|
|
|
void kvm_put_kvm(struct kvm *kvm);
|
2011-11-24 16:38:24 +07:00
|
|
|
void update_memslots(struct kvm_memslots *slots, struct kvm_memory_slot *new);
|
2008-03-30 20:01:25 +07:00
|
|
|
|
2010-04-19 16:41:23 +07:00
|
|
|
static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm)
|
|
|
|
{
|
|
|
|
return rcu_dereference_check(kvm->memslots,
|
|
|
|
srcu_read_lock_held(&kvm->srcu)
|
|
|
|
|| lockdep_is_held(&kvm->slots_lock));
|
|
|
|
}
|
|
|
|
|
2011-11-24 18:04:35 +07:00
|
|
|
static inline struct kvm_memory_slot *
|
|
|
|
id_to_memslot(struct kvm_memslots *slots, int id)
|
|
|
|
{
|
2011-11-24 16:41:54 +07:00
|
|
|
int index = slots->id_to_index[id];
|
|
|
|
struct kvm_memory_slot *slot;
|
2011-11-24 16:40:57 +07:00
|
|
|
|
2011-11-24 16:41:54 +07:00
|
|
|
slot = &slots->memslots[index];
|
2011-11-24 16:40:57 +07:00
|
|
|
|
2011-11-24 16:41:54 +07:00
|
|
|
WARN_ON(slot->id != id);
|
|
|
|
return slot;
|
2011-11-24 18:04:35 +07:00
|
|
|
}
|
|
|
|
|
2007-10-18 00:17:48 +07:00
|
|
|
extern struct page *bad_page;
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
|
2007-10-18 00:17:48 +07:00
|
|
|
int is_error_page(struct page *page);
|
2008-04-03 02:46:56 +07:00
|
|
|
int is_error_pfn(pfn_t pfn);
|
2011-07-12 02:28:54 +07:00
|
|
|
int is_noslot_pfn(pfn_t pfn);
|
|
|
|
int is_invalid_pfn(pfn_t pfn);
|
2007-11-12 03:02:22 +07:00
|
|
|
int kvm_is_error_hva(unsigned long addr);
|
2007-10-25 04:52:57 +07:00
|
|
|
int kvm_set_memory_region(struct kvm *kvm,
|
|
|
|
struct kvm_userspace_memory_region *mem,
|
|
|
|
int user_alloc);
|
2007-10-29 08:40:42 +07:00
|
|
|
int __kvm_set_memory_region(struct kvm *kvm,
|
|
|
|
struct kvm_userspace_memory_region *mem,
|
|
|
|
int user_alloc);
|
2012-02-08 11:02:18 +07:00
|
|
|
void kvm_arch_free_memslot(struct kvm_memory_slot *free,
|
|
|
|
struct kvm_memory_slot *dont);
|
|
|
|
int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages);
|
2009-12-23 23:35:18 +07:00
|
|
|
int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|
|
|
struct kvm_memory_slot *memslot,
|
|
|
|
struct kvm_memory_slot old,
|
|
|
|
struct kvm_userspace_memory_region *mem,
|
|
|
|
int user_alloc);
|
|
|
|
void kvm_arch_commit_memory_region(struct kvm *kvm,
|
2007-11-20 15:25:04 +07:00
|
|
|
struct kvm_userspace_memory_region *mem,
|
|
|
|
struct kvm_memory_slot old,
|
|
|
|
int user_alloc);
|
2012-02-08 11:02:18 +07:00
|
|
|
bool kvm_largepages_enabled(void);
|
2009-06-11 22:07:44 +07:00
|
|
|
void kvm_disable_largepages(void);
|
2008-07-11 06:49:31 +07:00
|
|
|
void kvm_arch_flush_shadow(struct kvm *kvm);
|
2009-12-23 23:35:23 +07:00
|
|
|
|
2010-08-22 18:11:43 +07:00
|
|
|
int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
|
|
|
|
int nr_pages);
|
|
|
|
|
2012-07-26 10:58:59 +07:00
|
|
|
struct page *get_bad_page(void);
|
2007-03-30 18:02:32 +07:00
|
|
|
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
|
2008-02-23 21:44:30 +07:00
|
|
|
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
|
2007-11-20 16:49:33 +07:00
|
|
|
void kvm_release_page_clean(struct page *page);
|
|
|
|
void kvm_release_page_dirty(struct page *page);
|
2008-04-03 02:46:56 +07:00
|
|
|
void kvm_set_page_dirty(struct page *page);
|
|
|
|
void kvm_set_page_accessed(struct page *page);
|
|
|
|
|
2012-07-17 20:56:16 +07:00
|
|
|
pfn_t hva_to_pfn_atomic(unsigned long addr);
|
2010-08-28 18:24:13 +07:00
|
|
|
pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn);
|
2010-10-22 23:18:18 +07:00
|
|
|
pfn_t gfn_to_pfn_async(struct kvm *kvm, gfn_t gfn, bool *async,
|
|
|
|
bool write_fault, bool *writable);
|
2008-04-03 02:46:56 +07:00
|
|
|
pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn);
|
2010-10-22 23:18:18 +07:00
|
|
|
pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
|
|
|
|
bool *writable);
|
2012-07-17 20:56:16 +07:00
|
|
|
pfn_t gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn);
|
2008-04-03 02:46:56 +07:00
|
|
|
void kvm_release_pfn_dirty(pfn_t);
|
|
|
|
void kvm_release_pfn_clean(pfn_t pfn);
|
|
|
|
void kvm_set_pfn_dirty(pfn_t pfn);
|
|
|
|
void kvm_set_pfn_accessed(pfn_t pfn);
|
|
|
|
void kvm_get_pfn(pfn_t pfn);
|
|
|
|
|
2007-10-02 03:14:18 +07:00
|
|
|
int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset,
|
|
|
|
int len);
|
2007-12-21 07:18:23 +07:00
|
|
|
int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data,
|
|
|
|
unsigned long len);
|
2007-10-02 03:14:18 +07:00
|
|
|
int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len);
|
2011-07-12 02:28:11 +07:00
|
|
|
int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
|
|
|
|
void *data, unsigned long len);
|
2007-10-02 03:14:18 +07:00
|
|
|
int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data,
|
|
|
|
int offset, int len);
|
|
|
|
int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
|
|
|
|
unsigned long len);
|
2010-10-18 20:22:23 +07:00
|
|
|
int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
|
|
|
|
void *data, unsigned long len);
|
|
|
|
int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
|
|
|
|
gpa_t gpa);
|
2007-10-02 03:14:18 +07:00
|
|
|
int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
|
|
|
|
int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long 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 17:21:36 +07:00
|
|
|
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
|
2007-10-25 04:57:46 +07:00
|
|
|
int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn);
|
2010-01-28 18:37:56 +07:00
|
|
|
unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
void mark_page_dirty(struct kvm *kvm, gfn_t gfn);
|
2010-10-18 20:22:23 +07:00
|
|
|
void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
|
|
|
gfn_t gfn);
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
|
2007-11-01 05:24:24 +07:00
|
|
|
void kvm_vcpu_block(struct kvm_vcpu *vcpu);
|
2012-03-09 04:44:24 +07:00
|
|
|
void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
|
2012-04-25 20:30:38 +07:00
|
|
|
bool kvm_vcpu_yield_to(struct kvm_vcpu *target);
|
2009-10-09 17:03:20 +07:00
|
|
|
void kvm_vcpu_on_spin(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 17:21:36 +07:00
|
|
|
void kvm_resched(struct kvm_vcpu *vcpu);
|
2007-06-14 20:27:40 +07:00
|
|
|
void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
|
|
|
|
void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
|
2010-11-23 10:13:00 +07:00
|
|
|
|
2007-06-07 23:18:30 +07:00
|
|
|
void kvm_flush_remote_tlbs(struct kvm *kvm);
|
2008-02-21 02:47:24 +07:00
|
|
|
void kvm_reload_remote_mmus(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 17:21:36 +07:00
|
|
|
|
2007-10-10 22:16:19 +07:00
|
|
|
long kvm_arch_dev_ioctl(struct file *filp,
|
|
|
|
unsigned int ioctl, unsigned long arg);
|
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-12 00:16:52 +07:00
|
|
|
long kvm_arch_vcpu_ioctl(struct file *filp,
|
|
|
|
unsigned int ioctl, unsigned long arg);
|
2012-01-04 16:25:23 +07:00
|
|
|
int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
|
2007-11-15 22:07:47 +07:00
|
|
|
|
|
|
|
int kvm_dev_ioctl_check_extension(long ext);
|
|
|
|
|
2007-11-18 19:29:43 +07:00
|
|
|
int kvm_get_dirty_log(struct kvm *kvm,
|
|
|
|
struct kvm_dirty_log *log, int *is_dirty);
|
|
|
|
int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
|
|
|
struct kvm_dirty_log *log);
|
|
|
|
|
2007-10-29 22:08:35 +07:00
|
|
|
int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
|
|
|
|
struct
|
|
|
|
kvm_userspace_memory_region *mem,
|
|
|
|
int user_alloc);
|
2012-07-24 19:51:20 +07:00
|
|
|
int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level);
|
2007-10-29 22:08:35 +07:00
|
|
|
long kvm_arch_vm_ioctl(struct file *filp,
|
|
|
|
unsigned int ioctl, unsigned long arg);
|
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-12 00:16:52 +07:00
|
|
|
|
2007-11-01 05:24:25 +07:00
|
|
|
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
|
|
|
|
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
|
|
|
|
|
2007-11-16 12:05:55 +07:00
|
|
|
int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_translation *tr);
|
|
|
|
|
2007-11-02 02:16:10 +07:00
|
|
|
int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs);
|
|
|
|
int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs);
|
|
|
|
int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_sregs *sregs);
|
|
|
|
int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_sregs *sregs);
|
2008-04-11 23:24:45 +07:00
|
|
|
int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_mp_state *mp_state);
|
|
|
|
int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_mp_state *mp_state);
|
2008-12-15 19:52:10 +07:00
|
|
|
int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
|
|
|
|
struct kvm_guest_debug *dbg);
|
2007-11-02 02:16:10 +07:00
|
|
|
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
|
|
|
|
|
2007-11-14 19:40:21 +07:00
|
|
|
int kvm_arch_init(void *opaque);
|
|
|
|
void kvm_arch_exit(void);
|
2007-10-10 22:16:19 +07:00
|
|
|
|
2007-11-14 19:38:21 +07:00
|
|
|
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
|
|
|
|
void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu);
|
|
|
|
|
|
|
|
void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu);
|
|
|
|
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
|
|
|
|
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
|
|
|
|
struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id);
|
2007-11-20 20:30:24 +07:00
|
|
|
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu);
|
2007-11-20 03:04:43 +07:00
|
|
|
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu);
|
2007-11-14 19:38:21 +07:00
|
|
|
|
|
|
|
int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu);
|
2009-09-15 16:37:46 +07:00
|
|
|
int kvm_arch_hardware_enable(void *garbage);
|
2007-11-14 19:38:21 +07:00
|
|
|
void kvm_arch_hardware_disable(void *garbage);
|
|
|
|
int kvm_arch_hardware_setup(void);
|
|
|
|
void kvm_arch_hardware_unsetup(void);
|
|
|
|
void kvm_arch_check_processor_compat(void *rtn);
|
2007-12-14 08:35:10 +07:00
|
|
|
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
|
2012-03-09 04:44:24 +07:00
|
|
|
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);
|
2007-11-14 19:38:21 +07:00
|
|
|
|
2007-11-18 17:43:45 +07:00
|
|
|
void kvm_free_physmem(struct kvm *kvm);
|
|
|
|
|
2012-05-20 11:15:07 +07:00
|
|
|
void *kvm_kvzalloc(unsigned long size);
|
|
|
|
void kvm_kvfree(const void *addr);
|
|
|
|
|
2010-11-09 23:02:49 +07:00
|
|
|
#ifndef __KVM_HAVE_ARCH_VM_ALLOC
|
|
|
|
static inline struct kvm *kvm_arch_alloc_vm(void)
|
|
|
|
{
|
|
|
|
return kzalloc(sizeof(struct kvm), GFP_KERNEL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void kvm_arch_free_vm(struct kvm *kvm)
|
|
|
|
{
|
|
|
|
kfree(kvm);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-03-09 04:44:24 +07:00
|
|
|
static inline wait_queue_head_t *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2012-03-14 04:35:01 +07:00
|
|
|
#ifdef __KVM_HAVE_ARCH_WQP
|
|
|
|
return vcpu->arch.wqp;
|
|
|
|
#else
|
2012-03-09 04:44:24 +07:00
|
|
|
return &vcpu->wq;
|
|
|
|
#endif
|
2012-03-14 04:35:01 +07:00
|
|
|
}
|
2012-03-09 04:44:24 +07:00
|
|
|
|
2012-01-04 16:25:20 +07:00
|
|
|
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type);
|
2007-11-18 17:43:45 +07:00
|
|
|
void kvm_arch_destroy_vm(struct kvm *kvm);
|
2008-10-06 12:47:38 +07:00
|
|
|
void kvm_free_all_assigned_devices(struct kvm *kvm);
|
2009-01-06 09:03:02 +07:00
|
|
|
void kvm_arch_sync_events(struct kvm *kvm);
|
2007-11-14 19:38:21 +07:00
|
|
|
|
2008-04-12 00:53:26 +07:00
|
|
|
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu);
|
2007-12-17 13:21:40 +07:00
|
|
|
void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
|
2007-12-11 19:36:00 +07:00
|
|
|
|
2012-07-26 10:58:59 +07:00
|
|
|
bool kvm_is_mmio_pfn(pfn_t pfn);
|
2008-09-27 09:55:40 +07:00
|
|
|
|
2008-09-14 07:48:28 +07:00
|
|
|
struct kvm_irq_ack_notifier {
|
|
|
|
struct hlist_node link;
|
|
|
|
unsigned gsi;
|
|
|
|
void (*irq_acked)(struct kvm_irq_ack_notifier *kian);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct kvm_assigned_dev_kernel {
|
|
|
|
struct kvm_irq_ack_notifier ack_notifier;
|
|
|
|
struct list_head list;
|
|
|
|
int assigned_dev_id;
|
2010-01-29 13:38:44 +07:00
|
|
|
int host_segnr;
|
2008-09-14 07:48:28 +07:00
|
|
|
int host_busnr;
|
|
|
|
int host_devfn;
|
2009-02-25 16:22:26 +07:00
|
|
|
unsigned int entries_nr;
|
2008-09-14 07:48:28 +07:00
|
|
|
int host_irq;
|
2008-12-02 19:16:33 +07:00
|
|
|
bool host_irq_disabled;
|
2012-02-28 20:19:54 +07:00
|
|
|
bool pci_2_3;
|
2009-02-25 16:22:26 +07:00
|
|
|
struct msix_entry *host_msix_entries;
|
2008-09-14 07:48:28 +07:00
|
|
|
int guest_irq;
|
2010-11-17 04:30:03 +07:00
|
|
|
struct msix_entry *guest_msix_entries;
|
2008-11-24 13:32:51 +07:00
|
|
|
unsigned long irq_requested_type;
|
2008-10-15 19:15:06 +07:00
|
|
|
int irq_source_id;
|
2008-12-08 22:29:53 +07:00
|
|
|
int flags;
|
2008-09-14 07:48:28 +07:00
|
|
|
struct pci_dev *dev;
|
|
|
|
struct kvm *kvm;
|
2010-11-17 04:30:03 +07:00
|
|
|
spinlock_t intx_lock;
|
2012-03-14 17:02:11 +07:00
|
|
|
spinlock_t intx_mask_lock;
|
2010-11-17 04:30:04 +07:00
|
|
|
char irq_name[32];
|
2011-05-10 23:02:39 +07:00
|
|
|
struct pci_saved_state *pci_saved_state;
|
2008-09-14 07:48:28 +07:00
|
|
|
};
|
2009-01-04 22:10:50 +07:00
|
|
|
|
|
|
|
struct kvm_irq_mask_notifier {
|
|
|
|
void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
|
|
|
|
int irq;
|
|
|
|
struct hlist_node link;
|
|
|
|
};
|
|
|
|
|
|
|
|
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
|
|
|
|
struct kvm_irq_mask_notifier *kimn);
|
|
|
|
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
|
|
|
|
struct kvm_irq_mask_notifier *kimn);
|
2010-07-11 19:32:23 +07:00
|
|
|
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
|
|
|
|
bool mask);
|
2009-01-04 22:10:50 +07:00
|
|
|
|
2009-08-24 15:54:20 +07:00
|
|
|
#ifdef __KVM_HAVE_IOAPIC
|
|
|
|
void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic,
|
|
|
|
union kvm_ioapic_redirect_entry *entry,
|
|
|
|
unsigned long *deliver_bitmask);
|
|
|
|
#endif
|
|
|
|
int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level);
|
2010-11-19 00:09:08 +07:00
|
|
|
int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
|
|
|
|
int irq_source_id, int level);
|
2009-01-28 00:12:38 +07:00
|
|
|
void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
|
2008-10-06 12:48:45 +07:00
|
|
|
void kvm_register_irq_ack_notifier(struct kvm *kvm,
|
|
|
|
struct kvm_irq_ack_notifier *kian);
|
2009-06-05 01:08:24 +07:00
|
|
|
void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
|
|
|
|
struct kvm_irq_ack_notifier *kian);
|
2008-10-15 19:15:06 +07:00
|
|
|
int kvm_request_irq_source_id(struct kvm *kvm);
|
|
|
|
void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
|
2008-09-14 07:48:28 +07:00
|
|
|
|
2009-04-27 19:35:43 +07:00
|
|
|
/* For vcpu->arch.iommu_flags */
|
|
|
|
#define KVM_IOMMU_CACHE_COHERENCY 0x1
|
|
|
|
|
2008-12-03 20:43:34 +07:00
|
|
|
#ifdef CONFIG_IOMMU_API
|
2009-12-23 23:35:20 +07:00
|
|
|
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
|
2012-04-11 22:51:49 +07:00
|
|
|
void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
|
2008-12-02 20:03:39 +07:00
|
|
|
int kvm_iommu_map_guest(struct kvm *kvm);
|
2008-09-14 07:48:28 +07:00
|
|
|
int kvm_iommu_unmap_guest(struct kvm *kvm);
|
2008-12-02 20:03:39 +07:00
|
|
|
int kvm_assign_device(struct kvm *kvm,
|
|
|
|
struct kvm_assigned_dev_kernel *assigned_dev);
|
2008-12-02 20:24:23 +07:00
|
|
|
int kvm_deassign_device(struct kvm *kvm,
|
|
|
|
struct kvm_assigned_dev_kernel *assigned_dev);
|
2008-12-03 20:43:34 +07:00
|
|
|
#else /* CONFIG_IOMMU_API */
|
2008-09-14 07:48:28 +07:00
|
|
|
static inline int kvm_iommu_map_pages(struct kvm *kvm,
|
2010-10-14 18:59:04 +07:00
|
|
|
struct kvm_memory_slot *slot)
|
2008-09-14 07:48:28 +07:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-04-11 22:51:49 +07:00
|
|
|
static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
|
|
|
|
struct kvm_memory_slot *slot)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-12-02 20:03:39 +07:00
|
|
|
static inline int kvm_iommu_map_guest(struct kvm *kvm)
|
2008-09-14 07:48:28 +07:00
|
|
|
{
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int kvm_iommu_unmap_guest(struct kvm *kvm)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2008-12-02 20:03:39 +07:00
|
|
|
|
|
|
|
static inline int kvm_assign_device(struct kvm *kvm,
|
|
|
|
struct kvm_assigned_dev_kernel *assigned_dev)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2008-12-02 20:24:23 +07:00
|
|
|
|
|
|
|
static inline int kvm_deassign_device(struct kvm *kvm,
|
|
|
|
struct kvm_assigned_dev_kernel *assigned_dev)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2008-12-03 20:43:34 +07:00
|
|
|
#endif /* CONFIG_IOMMU_API */
|
2008-09-14 07:48:28 +07:00
|
|
|
|
2007-10-15 22:00:19 +07:00
|
|
|
static inline void kvm_guest_enter(void)
|
|
|
|
{
|
2011-05-04 20:31:04 +07:00
|
|
|
BUG_ON(preemptible());
|
2007-10-18 19:39:10 +07:00
|
|
|
account_system_vtime(current);
|
2007-10-15 22:00:19 +07:00
|
|
|
current->flags |= PF_VCPU;
|
2011-05-04 20:31:04 +07:00
|
|
|
/* KVM does not hold any references to rcu protected data when it
|
|
|
|
* switches CPU into a guest mode. In fact switching to a guest mode
|
|
|
|
* is very similar to exiting to userspase from rcu point of view. In
|
|
|
|
* addition CPU may stay in a guest mode for quite a long time (up to
|
|
|
|
* one time slice). Lets treat guest mode as quiescent state, just like
|
|
|
|
* we do with user-mode execution.
|
|
|
|
*/
|
|
|
|
rcu_virt_note_context_switch(smp_processor_id());
|
2007-10-15 22:00:19 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void kvm_guest_exit(void)
|
|
|
|
{
|
2007-10-18 19:39:10 +07:00
|
|
|
account_system_vtime(current);
|
2007-10-15 22:00:19 +07:00
|
|
|
current->flags &= ~PF_VCPU;
|
|
|
|
}
|
|
|
|
|
2012-01-13 03:09:51 +07:00
|
|
|
/*
|
|
|
|
* search_memslots() and __gfn_to_memslot() are here because they are
|
|
|
|
* used in non-modular code in arch/powerpc/kvm/book3s_hv_rm_mmu.c.
|
|
|
|
* gfn_to_memslot() itself isn't here as an inline because that would
|
|
|
|
* bloat other code too much.
|
|
|
|
*/
|
|
|
|
static inline struct kvm_memory_slot *
|
|
|
|
search_memslots(struct kvm_memslots *slots, gfn_t gfn)
|
|
|
|
{
|
|
|
|
struct kvm_memory_slot *memslot;
|
|
|
|
|
|
|
|
kvm_for_each_memslot(memslot, slots)
|
|
|
|
if (gfn >= memslot->base_gfn &&
|
|
|
|
gfn < memslot->base_gfn + memslot->npages)
|
|
|
|
return memslot;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct kvm_memory_slot *
|
|
|
|
__gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn)
|
|
|
|
{
|
|
|
|
return search_memslots(slots, gfn);
|
|
|
|
}
|
|
|
|
|
2011-03-09 14:41:59 +07:00
|
|
|
static inline int memslot_id(struct kvm *kvm, gfn_t gfn)
|
|
|
|
{
|
|
|
|
return gfn_to_memslot(kvm, gfn)->id;
|
|
|
|
}
|
|
|
|
|
2012-02-08 10:59:10 +07:00
|
|
|
static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
|
|
|
|
{
|
|
|
|
/* KVM_HPAGE_GFN_SHIFT(PT_PAGE_TABLE_LEVEL) must be 0. */
|
|
|
|
return (gfn >> KVM_HPAGE_GFN_SHIFT(level)) -
|
|
|
|
(base_gfn >> KVM_HPAGE_GFN_SHIFT(level));
|
|
|
|
}
|
|
|
|
|
2012-07-02 15:54:30 +07:00
|
|
|
static inline gfn_t
|
|
|
|
hva_to_gfn_memslot(unsigned long hva, struct kvm_memory_slot *slot)
|
|
|
|
{
|
|
|
|
gfn_t gfn_offset = (hva - slot->userspace_addr) >> PAGE_SHIFT;
|
|
|
|
|
|
|
|
return slot->base_gfn + gfn_offset;
|
|
|
|
}
|
|
|
|
|
2010-08-22 18:10:28 +07:00
|
|
|
static inline unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot,
|
|
|
|
gfn_t gfn)
|
|
|
|
{
|
|
|
|
return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE;
|
|
|
|
}
|
|
|
|
|
2007-11-21 19:44:45 +07:00
|
|
|
static inline gpa_t gfn_to_gpa(gfn_t gfn)
|
|
|
|
{
|
|
|
|
return (gpa_t)gfn << PAGE_SHIFT;
|
|
|
|
}
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
|
2010-09-10 22:30:48 +07:00
|
|
|
static inline gfn_t gpa_to_gfn(gpa_t gpa)
|
|
|
|
{
|
|
|
|
return (gfn_t)(gpa >> PAGE_SHIFT);
|
|
|
|
}
|
|
|
|
|
2008-09-14 07:48:28 +07:00
|
|
|
static inline hpa_t pfn_to_hpa(pfn_t pfn)
|
|
|
|
{
|
|
|
|
return (hpa_t)pfn << PAGE_SHIFT;
|
|
|
|
}
|
|
|
|
|
2008-05-27 22:10:20 +07:00
|
|
|
static inline void kvm_migrate_timers(struct kvm_vcpu *vcpu)
|
2008-01-16 17:49:30 +07:00
|
|
|
{
|
|
|
|
set_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests);
|
|
|
|
}
|
|
|
|
|
2007-11-18 21:24:12 +07:00
|
|
|
enum kvm_stat_kind {
|
|
|
|
KVM_STAT_VM,
|
|
|
|
KVM_STAT_VCPU,
|
|
|
|
};
|
|
|
|
|
2007-11-01 05:24:23 +07:00
|
|
|
struct kvm_stats_debugfs_item {
|
|
|
|
const char *name;
|
|
|
|
int offset;
|
2007-11-18 21:24:12 +07:00
|
|
|
enum kvm_stat_kind kind;
|
2007-11-01 05:24:23 +07:00
|
|
|
struct dentry *dentry;
|
|
|
|
};
|
|
|
|
extern struct kvm_stats_debugfs_item debugfs_entries[];
|
2008-04-16 04:05:42 +07:00
|
|
|
extern struct dentry *kvm_debugfs_dir;
|
2008-04-10 19:47:53 +07:00
|
|
|
|
2012-06-16 02:07:24 +07:00
|
|
|
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
|
2008-07-25 21:24:52 +07:00
|
|
|
static inline int mmu_notifier_retry(struct kvm_vcpu *vcpu, unsigned long mmu_seq)
|
|
|
|
{
|
|
|
|
if (unlikely(vcpu->kvm->mmu_notifier_count))
|
|
|
|
return 1;
|
|
|
|
/*
|
2011-12-12 19:37:21 +07:00
|
|
|
* Ensure the read of mmu_notifier_count happens before the read
|
|
|
|
* of mmu_notifier_seq. This interacts with the smp_wmb() in
|
|
|
|
* mmu_notifier_invalidate_range_end to make sure that the caller
|
|
|
|
* either sees the old (non-zero) value of mmu_notifier_count or
|
|
|
|
* the new (incremented) value of mmu_notifier_seq.
|
|
|
|
* PowerPC Book3s HV KVM calls this under a per-page lock
|
|
|
|
* rather than under kvm->mmu_lock, for scalability, so
|
|
|
|
* can't rely on kvm->mmu_lock to keep things ordered.
|
2008-07-25 21:24:52 +07:00
|
|
|
*/
|
2011-12-12 19:37:21 +07:00
|
|
|
smp_rmb();
|
2008-07-25 21:24:52 +07:00
|
|
|
if (vcpu->kvm->mmu_notifier_seq != mmu_seq)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-06-16 02:07:02 +07:00
|
|
|
#ifdef KVM_CAP_IRQ_ROUTING
|
2008-11-19 18:58:46 +07:00
|
|
|
|
|
|
|
#define KVM_MAX_IRQ_ROUTES 1024
|
|
|
|
|
|
|
|
int kvm_setup_default_irq_routing(struct kvm *kvm);
|
|
|
|
int kvm_set_irq_routing(struct kvm *kvm,
|
|
|
|
const struct kvm_irq_routing_entry *entries,
|
|
|
|
unsigned nr,
|
|
|
|
unsigned flags);
|
|
|
|
void kvm_free_irq_routing(struct kvm *kvm);
|
|
|
|
|
2012-03-30 02:14:12 +07:00
|
|
|
int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
|
|
|
|
|
2008-11-19 18:58:46 +07:00
|
|
|
#else
|
|
|
|
|
|
|
|
static inline void kvm_free_irq_routing(struct kvm *kvm) {}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-05-20 21:30:49 +07:00
|
|
|
#ifdef CONFIG_HAVE_KVM_EVENTFD
|
|
|
|
|
KVM: add ioeventfd support
ioeventfd is a mechanism to register PIO/MMIO regions to trigger an eventfd
signal when written to by a guest. Host userspace can register any
arbitrary IO address with a corresponding eventfd and then pass the eventfd
to a specific end-point of interest for handling.
Normal IO requires a blocking round-trip since the operation may cause
side-effects in the emulated model or may return data to the caller.
Therefore, an IO in KVM traps from the guest to the host, causes a VMX/SVM
"heavy-weight" exit back to userspace, and is ultimately serviced by qemu's
device model synchronously before returning control back to the vcpu.
However, there is a subclass of IO which acts purely as a trigger for
other IO (such as to kick off an out-of-band DMA request, etc). For these
patterns, the synchronous call is particularly expensive since we really
only want to simply get our notification transmitted asychronously and
return as quickly as possible. All the sychronous infrastructure to ensure
proper data-dependencies are met in the normal IO case are just unecessary
overhead for signalling. This adds additional computational load on the
system, as well as latency to the signalling path.
Therefore, we provide a mechanism for registration of an in-kernel trigger
point that allows the VCPU to only require a very brief, lightweight
exit just long enough to signal an eventfd. This also means that any
clients compatible with the eventfd interface (which includes userspace
and kernelspace equally well) can now register to be notified. The end
result should be a more flexible and higher performance notification API
for the backend KVM hypervisor and perhipheral components.
To test this theory, we built a test-harness called "doorbell". This
module has a function called "doorbell_ring()" which simply increments a
counter for each time the doorbell is signaled. It supports signalling
from either an eventfd, or an ioctl().
We then wired up two paths to the doorbell: One via QEMU via a registered
io region and through the doorbell ioctl(). The other is direct via
ioeventfd.
You can download this test harness here:
ftp://ftp.novell.com/dev/ghaskins/doorbell.tar.bz2
The measured results are as follows:
qemu-mmio: 110000 iops, 9.09us rtt
ioeventfd-mmio: 200100 iops, 5.00us rtt
ioeventfd-pio: 367300 iops, 2.72us rtt
I didn't measure qemu-pio, because I have to figure out how to register a
PIO region with qemu's device model, and I got lazy. However, for now we
can extrapolate based on the data from the NULLIO runs of +2.56us for MMIO,
and -350ns for HC, we get:
qemu-pio: 153139 iops, 6.53us rtt
ioeventfd-hc: 412585 iops, 2.37us rtt
these are just for fun, for now, until I can gather more data.
Here is a graph for your convenience:
http://developer.novell.com/wiki/images/7/76/Iofd-chart.png
The conclusion to draw is that we save about 4us by skipping the userspace
hop.
--------------------
Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2009-07-08 04:08:49 +07:00
|
|
|
void kvm_eventfd_init(struct kvm *kvm);
|
2012-06-29 22:56:08 +07:00
|
|
|
int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
|
2009-05-20 21:30:49 +07:00
|
|
|
void kvm_irqfd_release(struct kvm *kvm);
|
2010-11-19 00:09:08 +07:00
|
|
|
void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *);
|
KVM: add ioeventfd support
ioeventfd is a mechanism to register PIO/MMIO regions to trigger an eventfd
signal when written to by a guest. Host userspace can register any
arbitrary IO address with a corresponding eventfd and then pass the eventfd
to a specific end-point of interest for handling.
Normal IO requires a blocking round-trip since the operation may cause
side-effects in the emulated model or may return data to the caller.
Therefore, an IO in KVM traps from the guest to the host, causes a VMX/SVM
"heavy-weight" exit back to userspace, and is ultimately serviced by qemu's
device model synchronously before returning control back to the vcpu.
However, there is a subclass of IO which acts purely as a trigger for
other IO (such as to kick off an out-of-band DMA request, etc). For these
patterns, the synchronous call is particularly expensive since we really
only want to simply get our notification transmitted asychronously and
return as quickly as possible. All the sychronous infrastructure to ensure
proper data-dependencies are met in the normal IO case are just unecessary
overhead for signalling. This adds additional computational load on the
system, as well as latency to the signalling path.
Therefore, we provide a mechanism for registration of an in-kernel trigger
point that allows the VCPU to only require a very brief, lightweight
exit just long enough to signal an eventfd. This also means that any
clients compatible with the eventfd interface (which includes userspace
and kernelspace equally well) can now register to be notified. The end
result should be a more flexible and higher performance notification API
for the backend KVM hypervisor and perhipheral components.
To test this theory, we built a test-harness called "doorbell". This
module has a function called "doorbell_ring()" which simply increments a
counter for each time the doorbell is signaled. It supports signalling
from either an eventfd, or an ioctl().
We then wired up two paths to the doorbell: One via QEMU via a registered
io region and through the doorbell ioctl(). The other is direct via
ioeventfd.
You can download this test harness here:
ftp://ftp.novell.com/dev/ghaskins/doorbell.tar.bz2
The measured results are as follows:
qemu-mmio: 110000 iops, 9.09us rtt
ioeventfd-mmio: 200100 iops, 5.00us rtt
ioeventfd-pio: 367300 iops, 2.72us rtt
I didn't measure qemu-pio, because I have to figure out how to register a
PIO region with qemu's device model, and I got lazy. However, for now we
can extrapolate based on the data from the NULLIO runs of +2.56us for MMIO,
and -350ns for HC, we get:
qemu-pio: 153139 iops, 6.53us rtt
ioeventfd-hc: 412585 iops, 2.37us rtt
these are just for fun, for now, until I can gather more data.
Here is a graph for your convenience:
http://developer.novell.com/wiki/images/7/76/Iofd-chart.png
The conclusion to draw is that we save about 4us by skipping the userspace
hop.
--------------------
Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2009-07-08 04:08:49 +07:00
|
|
|
int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
|
2009-05-20 21:30:49 +07:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
KVM: add ioeventfd support
ioeventfd is a mechanism to register PIO/MMIO regions to trigger an eventfd
signal when written to by a guest. Host userspace can register any
arbitrary IO address with a corresponding eventfd and then pass the eventfd
to a specific end-point of interest for handling.
Normal IO requires a blocking round-trip since the operation may cause
side-effects in the emulated model or may return data to the caller.
Therefore, an IO in KVM traps from the guest to the host, causes a VMX/SVM
"heavy-weight" exit back to userspace, and is ultimately serviced by qemu's
device model synchronously before returning control back to the vcpu.
However, there is a subclass of IO which acts purely as a trigger for
other IO (such as to kick off an out-of-band DMA request, etc). For these
patterns, the synchronous call is particularly expensive since we really
only want to simply get our notification transmitted asychronously and
return as quickly as possible. All the sychronous infrastructure to ensure
proper data-dependencies are met in the normal IO case are just unecessary
overhead for signalling. This adds additional computational load on the
system, as well as latency to the signalling path.
Therefore, we provide a mechanism for registration of an in-kernel trigger
point that allows the VCPU to only require a very brief, lightweight
exit just long enough to signal an eventfd. This also means that any
clients compatible with the eventfd interface (which includes userspace
and kernelspace equally well) can now register to be notified. The end
result should be a more flexible and higher performance notification API
for the backend KVM hypervisor and perhipheral components.
To test this theory, we built a test-harness called "doorbell". This
module has a function called "doorbell_ring()" which simply increments a
counter for each time the doorbell is signaled. It supports signalling
from either an eventfd, or an ioctl().
We then wired up two paths to the doorbell: One via QEMU via a registered
io region and through the doorbell ioctl(). The other is direct via
ioeventfd.
You can download this test harness here:
ftp://ftp.novell.com/dev/ghaskins/doorbell.tar.bz2
The measured results are as follows:
qemu-mmio: 110000 iops, 9.09us rtt
ioeventfd-mmio: 200100 iops, 5.00us rtt
ioeventfd-pio: 367300 iops, 2.72us rtt
I didn't measure qemu-pio, because I have to figure out how to register a
PIO region with qemu's device model, and I got lazy. However, for now we
can extrapolate based on the data from the NULLIO runs of +2.56us for MMIO,
and -350ns for HC, we get:
qemu-pio: 153139 iops, 6.53us rtt
ioeventfd-hc: 412585 iops, 2.37us rtt
these are just for fun, for now, until I can gather more data.
Here is a graph for your convenience:
http://developer.novell.com/wiki/images/7/76/Iofd-chart.png
The conclusion to draw is that we save about 4us by skipping the userspace
hop.
--------------------
Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2009-07-08 04:08:49 +07:00
|
|
|
static inline void kvm_eventfd_init(struct kvm *kvm) {}
|
2010-11-19 00:09:08 +07:00
|
|
|
|
2012-06-29 22:56:08 +07:00
|
|
|
static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
|
2009-05-20 21:30:49 +07:00
|
|
|
{
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void kvm_irqfd_release(struct kvm *kvm) {}
|
2010-11-19 00:09:08 +07:00
|
|
|
|
2010-11-25 16:25:44 +07:00
|
|
|
#ifdef CONFIG_HAVE_KVM_IRQCHIP
|
2010-11-19 00:09:08 +07:00
|
|
|
static inline void kvm_irq_routing_update(struct kvm *kvm,
|
|
|
|
struct kvm_irq_routing_table *irq_rt)
|
|
|
|
{
|
|
|
|
rcu_assign_pointer(kvm->irq_routing, irq_rt);
|
|
|
|
}
|
2010-11-25 16:25:44 +07:00
|
|
|
#endif
|
2010-11-19 00:09:08 +07:00
|
|
|
|
KVM: add ioeventfd support
ioeventfd is a mechanism to register PIO/MMIO regions to trigger an eventfd
signal when written to by a guest. Host userspace can register any
arbitrary IO address with a corresponding eventfd and then pass the eventfd
to a specific end-point of interest for handling.
Normal IO requires a blocking round-trip since the operation may cause
side-effects in the emulated model or may return data to the caller.
Therefore, an IO in KVM traps from the guest to the host, causes a VMX/SVM
"heavy-weight" exit back to userspace, and is ultimately serviced by qemu's
device model synchronously before returning control back to the vcpu.
However, there is a subclass of IO which acts purely as a trigger for
other IO (such as to kick off an out-of-band DMA request, etc). For these
patterns, the synchronous call is particularly expensive since we really
only want to simply get our notification transmitted asychronously and
return as quickly as possible. All the sychronous infrastructure to ensure
proper data-dependencies are met in the normal IO case are just unecessary
overhead for signalling. This adds additional computational load on the
system, as well as latency to the signalling path.
Therefore, we provide a mechanism for registration of an in-kernel trigger
point that allows the VCPU to only require a very brief, lightweight
exit just long enough to signal an eventfd. This also means that any
clients compatible with the eventfd interface (which includes userspace
and kernelspace equally well) can now register to be notified. The end
result should be a more flexible and higher performance notification API
for the backend KVM hypervisor and perhipheral components.
To test this theory, we built a test-harness called "doorbell". This
module has a function called "doorbell_ring()" which simply increments a
counter for each time the doorbell is signaled. It supports signalling
from either an eventfd, or an ioctl().
We then wired up two paths to the doorbell: One via QEMU via a registered
io region and through the doorbell ioctl(). The other is direct via
ioeventfd.
You can download this test harness here:
ftp://ftp.novell.com/dev/ghaskins/doorbell.tar.bz2
The measured results are as follows:
qemu-mmio: 110000 iops, 9.09us rtt
ioeventfd-mmio: 200100 iops, 5.00us rtt
ioeventfd-pio: 367300 iops, 2.72us rtt
I didn't measure qemu-pio, because I have to figure out how to register a
PIO region with qemu's device model, and I got lazy. However, for now we
can extrapolate based on the data from the NULLIO runs of +2.56us for MMIO,
and -350ns for HC, we get:
qemu-pio: 153139 iops, 6.53us rtt
ioeventfd-hc: 412585 iops, 2.37us rtt
these are just for fun, for now, until I can gather more data.
Here is a graph for your convenience:
http://developer.novell.com/wiki/images/7/76/Iofd-chart.png
The conclusion to draw is that we save about 4us by skipping the userspace
hop.
--------------------
Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2009-07-08 04:08:49 +07:00
|
|
|
static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
2009-05-20 21:30:49 +07:00
|
|
|
|
|
|
|
#endif /* CONFIG_HAVE_KVM_EVENTFD */
|
|
|
|
|
2009-06-09 19:56:28 +07:00
|
|
|
#ifdef CONFIG_KVM_APIC_ARCHITECTURE
|
2009-06-09 19:56:26 +07:00
|
|
|
static inline bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2009-06-17 20:07:59 +07:00
|
|
|
return vcpu->kvm->bsp_vcpu_id == vcpu->vcpu_id;
|
2009-06-09 19:56:26 +07:00
|
|
|
}
|
2012-03-05 19:23:29 +07:00
|
|
|
|
|
|
|
bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; }
|
|
|
|
|
[PATCH] kvm: userspace interface
web site: http://kvm.sourceforge.net
mailing list: kvm-devel@lists.sourceforge.net
(http://lists.sourceforge.net/lists/listinfo/kvm-devel)
The following patchset adds a driver for Intel's hardware virtualization
extensions to the x86 architecture. The driver adds a character device
(/dev/kvm) that exposes the virtualization capabilities to userspace. Using
this driver, a process can run a virtual machine (a "guest") in a fully
virtualized PC containing its own virtual hard disks, network adapters, and
display.
Using this driver, one can start multiple virtual machines on a host.
Each virtual machine is a process on the host; a virtual cpu is a thread in
that process. kill(1), nice(1), top(1) work as expected. In effect, the
driver adds a third execution mode to the existing two: we now have kernel
mode, user mode, and guest mode. Guest mode has its own address space mapping
guest physical memory (which is accessible to user mode by mmap()ing
/dev/kvm). Guest mode has no access to any I/O devices; any such access is
intercepted and directed to user mode for emulation.
The driver supports i386 and x86_64 hosts and guests. All combinations are
allowed except x86_64 guest on i386 host. For i386 guests and hosts, both pae
and non-pae paging modes are supported.
SMP hosts and UP guests are supported. At the moment only Intel
hardware is supported, but AMD virtualization support is being worked on.
Performance currently is non-stellar due to the naive implementation of the
mmu virtualization, which throws away most of the shadow page table entries
every context switch. We plan to address this in two ways:
- cache shadow page tables across tlb flushes
- wait until AMD and Intel release processors with nested page tables
Currently a virtual desktop is responsive but consumes a lot of CPU. Under
Windows I tried playing pinball and watching a few flash movies; with a recent
CPU one can hardly feel the virtualization. Linux/X is slower, probably due
to X being in a separate process.
In addition to the driver, you need a slightly modified qemu to provide I/O
device emulation and the BIOS.
Caveats (akpm: might no longer be true):
- The Windows install currently bluescreens due to a problem with the
virtual APIC. We are working on a fix. A temporary workaround is to
use an existing image or install through qemu
- Windows 64-bit does not work. That's also true for qemu, so it's
probably a problem with the device model.
[bero@arklinux.org: build fix]
[simon.kagstrom@bth.se: build fix, other fixes]
[uril@qumranet.com: KVM: Expose interrupt bitmap]
[akpm@osdl.org: i386 build fix]
[mingo@elte.hu: i386 fixes]
[rdreier@cisco.com: add log levels to all printks]
[randy.dunlap@oracle.com: Fix sparse NULL and C99 struct init warnings]
[anthony@codemonkey.ws: KVM: AMD SVM: 32-bit host support]
Signed-off-by: Yaniv Kamay <yaniv@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Cc: Simon Kagstrom <simon.kagstrom@bth.se>
Cc: Bernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: Uri Lublin <uril@qumranet.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-10 17:21:36 +07:00
|
|
|
#endif
|
2009-08-26 18:57:50 +07:00
|
|
|
|
|
|
|
#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
|
|
|
|
|
|
|
|
long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
|
|
|
|
unsigned long arg);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
|
|
|
|
unsigned long arg)
|
|
|
|
{
|
|
|
|
return -ENOTTY;
|
|
|
|
}
|
|
|
|
|
2009-06-09 19:56:28 +07:00
|
|
|
#endif
|
2009-08-26 18:57:50 +07:00
|
|
|
|
2010-05-10 16:34:53 +07:00
|
|
|
static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
set_bit(req, &vcpu->requests);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
|
|
|
|
{
|
2010-05-10 17:08:26 +07:00
|
|
|
if (test_bit(req, &vcpu->requests)) {
|
|
|
|
clear_bit(req, &vcpu->requests);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2010-05-10 16:34:53 +07:00
|
|
|
}
|
|
|
|
|
2012-07-18 20:37:46 +07:00
|
|
|
#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
|
|
|
|
|
|
|
|
static inline void kvm_vcpu_set_in_spin_loop(struct kvm_vcpu *vcpu, bool val)
|
|
|
|
{
|
|
|
|
vcpu->spin_loop.in_spin_loop = val;
|
|
|
|
}
|
|
|
|
static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
|
|
|
|
{
|
|
|
|
vcpu->spin_loop.dy_eligible = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* !CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
|
|
|
|
|
|
|
|
static inline void kvm_vcpu_set_in_spin_loop(struct kvm_vcpu *vcpu, bool val)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-07-19 16:47:52 +07:00
|
|
|
static inline bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-18 20:37:46 +07:00
|
|
|
#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
|
2009-08-26 18:57:50 +07:00
|
|
|
#endif
|
|
|
|
|