aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2007-09-17 15:57:50 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:46 -0500
commit7aa81cc04781b5b99a0647ec04533599d78cd219 (patch)
tree6ac8854faf3db2bc499e2c105fdfdab95df52170 /include/linux
parentaca7f96600b170e470b3056aba0ed8d7df8d330d (diff)
KVM: Refactor hypercall infrastructure (v3)
This patch refactors the current hypercall infrastructure to better support live migration and SMP. It eliminates the hypercall page by trapping the UD exception that would occur if you used the wrong hypercall instruction for the underlying architecture and replacing it with the right one lazily. A fall-out of this patch is that the unhandled hypercalls no longer trap to userspace. There is very little reason though to use a hypercall to communicate with userspace as PIO or MMIO can be used. There is no code in tree that uses userspace hypercalls. [avi: fix #ud injection on vmx] Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/kvm_para.h159
1 files changed, 98 insertions, 61 deletions
diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h
index 3b292565a693..cc5dfb433706 100644
--- a/include/linux/kvm_para.h
+++ b/include/linux/kvm_para.h
@@ -1,73 +1,110 @@
1#ifndef __LINUX_KVM_PARA_H 1#ifndef __LINUX_KVM_PARA_H
2#define __LINUX_KVM_PARA_H 2#define __LINUX_KVM_PARA_H
3 3
4/* 4/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It
5 * Guest OS interface for KVM paravirtualization 5 * should be used to determine that a VM is running under KVM.
6 *
7 * Note: this interface is totally experimental, and is certain to change
8 * as we make progress.
9 */ 6 */
7#define KVM_CPUID_SIGNATURE 0x40000000
10 8
11/* 9/* This CPUID returns a feature bitmap in eax. Before enabling a particular
12 * Per-VCPU descriptor area shared between guest and host. Writable to 10 * paravirtualization, the appropriate feature bit should be checked.
13 * both guest and host. Registered with the host by the guest when
14 * a guest acknowledges paravirtual mode.
15 *
16 * NOTE: all addresses are guest-physical addresses (gpa), to make it
17 * easier for the hypervisor to map between the various addresses.
18 */
19struct kvm_vcpu_para_state {
20 /*
21 * API version information for compatibility. If there's any support
22 * mismatch (too old host trying to execute too new guest) then
23 * the host will deny entry into paravirtual mode. Any other
24 * combination (new host + old guest and new host + new guest)
25 * is supposed to work - new host versions will support all old
26 * guest API versions.
27 */
28 u32 guest_version;
29 u32 host_version;
30 u32 size;
31 u32 ret;
32
33 /*
34 * The address of the vm exit instruction (VMCALL or VMMCALL),
35 * which the host will patch according to the CPU model the
36 * VM runs on:
37 */
38 u64 hypercall_gpa;
39
40} __attribute__ ((aligned(PAGE_SIZE)));
41
42#define KVM_PARA_API_VERSION 1
43
44/*
45 * This is used for an RDMSR's ECX parameter to probe for a KVM host.
46 * Hopefully no CPU vendor will use up this number. This is placed well
47 * out of way of the typical space occupied by CPU vendors' MSR indices,
48 * and we think (or at least hope) it wont be occupied in the future
49 * either.
50 */ 11 */
51#define MSR_KVM_API_MAGIC 0x87655678 12#define KVM_CPUID_FEATURES 0x40000001
52 13
53#define KVM_EINVAL 1 14/* Return values for hypercalls */
15#define KVM_ENOSYS 1000
54 16
55/* 17#ifdef __KERNEL__
56 * Hypercall calling convention: 18#include <asm/processor.h>
57 * 19
58 * Each hypercall may have 0-6 parameters. 20/* This instruction is vmcall. On non-VT architectures, it will generate a
59 * 21 * trap that we will then rewrite to the appropriate instruction.
60 * 64-bit hypercall index is in RAX, goes from 0 to __NR_hypercalls-1 22 */
61 * 23#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
62 * 64-bit parameters 1-6 are in the standard gcc x86_64 calling convention 24
63 * order: RDI, RSI, RDX, RCX, R8, R9. 25/* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun
64 * 26 * instruction. The hypervisor may replace it with something else but only the
65 * 32-bit index is EBX, parameters are: EAX, ECX, EDX, ESI, EDI, EBP. 27 * instructions are guaranteed to be supported.
66 * (the first 3 are according to the gcc regparm calling convention)
67 * 28 *
68 * No registers are clobbered by the hypercall, except that the 29 * Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively.
69 * return value is in RAX. 30 * The hypercall number should be placed in rax and the return value will be
31 * placed in rax. No other registers will be clobbered unless explicited
32 * noted by the particular hypercall.
70 */ 33 */
71#define __NR_hypercalls 0 34
35static inline long kvm_hypercall0(unsigned int nr)
36{
37 long ret;
38 asm volatile(KVM_HYPERCALL
39 : "=a"(ret)
40 : "a"(nr));
41 return ret;
42}
43
44static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
45{
46 long ret;
47 asm volatile(KVM_HYPERCALL
48 : "=a"(ret)
49 : "a"(nr), "b"(p1));
50 return ret;
51}
52
53static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
54 unsigned long p2)
55{
56 long ret;
57 asm volatile(KVM_HYPERCALL
58 : "=a"(ret)
59 : "a"(nr), "b"(p1), "c"(p2));
60 return ret;
61}
62
63static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
64 unsigned long p2, unsigned long p3)
65{
66 long ret;
67 asm volatile(KVM_HYPERCALL
68 : "=a"(ret)
69 : "a"(nr), "b"(p1), "c"(p2), "d"(p3));
70 return ret;
71}
72
73static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
74 unsigned long p2, unsigned long p3,
75 unsigned long p4)
76{
77 long ret;
78 asm volatile(KVM_HYPERCALL
79 : "=a"(ret)
80 : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4));
81 return ret;
82}
83
84static inline int kvm_para_available(void)
85{
86 unsigned int eax, ebx, ecx, edx;
87 char signature[13];
88
89 cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
90 memcpy(signature + 0, &ebx, 4);
91 memcpy(signature + 4, &ecx, 4);
92 memcpy(signature + 8, &edx, 4);
93 signature[12] = 0;
94
95 if (strcmp(signature, "KVMKVMKVM") == 0)
96 return 1;
97
98 return 0;
99}
100
101static inline int kvm_para_has_feature(unsigned int feature)
102{
103 if (cpuid_eax(KVM_CPUID_FEATURES) & (1UL << feature))
104 return 1;
105 return 0;
106}
107
108#endif
72 109
73#endif 110#endif