diff options
author | Carsten Otte <cotte@de.ibm.com> | 2007-10-10 11:16:19 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:52:51 -0500 |
commit | 043405e10001fe7aae60c46a57189515f13a6468 (patch) | |
tree | a2f2e56117b200aeed70a853489b8e669a48fe15 /drivers/kvm/x86.c | |
parent | 6fc138d2278078990f597cb1f62fde9e5b458f96 (diff) |
KVM: Move x86 msr handling to new files x86.[ch]
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86.c')
-rw-r--r-- | drivers/kvm/x86.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c new file mode 100644 index 000000000000..437902cf178d --- /dev/null +++ b/drivers/kvm/x86.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Kernel-based Virtual Machine driver for Linux | ||
3 | * | ||
4 | * derived from drivers/kvm/kvm_main.c | ||
5 | * | ||
6 | * Copyright (C) 2006 Qumranet, Inc. | ||
7 | * | ||
8 | * Authors: | ||
9 | * Avi Kivity <avi@qumranet.com> | ||
10 | * Yaniv Kamay <yaniv@qumranet.com> | ||
11 | * | ||
12 | * This work is licensed under the terms of the GNU GPL, version 2. See | ||
13 | * the COPYING file in the top-level directory. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include "x86.h" | ||
18 | |||
19 | #include <asm/uaccess.h> | ||
20 | |||
21 | /* | ||
22 | * List of msr numbers which we expose to userspace through KVM_GET_MSRS | ||
23 | * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST. | ||
24 | * | ||
25 | * This list is modified at module load time to reflect the | ||
26 | * capabilities of the host cpu. | ||
27 | */ | ||
28 | static u32 msrs_to_save[] = { | ||
29 | MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, | ||
30 | MSR_K6_STAR, | ||
31 | #ifdef CONFIG_X86_64 | ||
32 | MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, | ||
33 | #endif | ||
34 | MSR_IA32_TIME_STAMP_COUNTER, | ||
35 | }; | ||
36 | |||
37 | static unsigned num_msrs_to_save; | ||
38 | |||
39 | static u32 emulated_msrs[] = { | ||
40 | MSR_IA32_MISC_ENABLE, | ||
41 | }; | ||
42 | |||
43 | long kvm_arch_dev_ioctl(struct file *filp, | ||
44 | unsigned int ioctl, unsigned long arg) | ||
45 | { | ||
46 | void __user *argp = (void __user *)arg; | ||
47 | long r; | ||
48 | |||
49 | switch (ioctl) { | ||
50 | case KVM_GET_MSR_INDEX_LIST: { | ||
51 | struct kvm_msr_list __user *user_msr_list = argp; | ||
52 | struct kvm_msr_list msr_list; | ||
53 | unsigned n; | ||
54 | |||
55 | r = -EFAULT; | ||
56 | if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) | ||
57 | goto out; | ||
58 | n = msr_list.nmsrs; | ||
59 | msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); | ||
60 | if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) | ||
61 | goto out; | ||
62 | r = -E2BIG; | ||
63 | if (n < num_msrs_to_save) | ||
64 | goto out; | ||
65 | r = -EFAULT; | ||
66 | if (copy_to_user(user_msr_list->indices, &msrs_to_save, | ||
67 | num_msrs_to_save * sizeof(u32))) | ||
68 | goto out; | ||
69 | if (copy_to_user(user_msr_list->indices | ||
70 | + num_msrs_to_save * sizeof(u32), | ||
71 | &emulated_msrs, | ||
72 | ARRAY_SIZE(emulated_msrs) * sizeof(u32))) | ||
73 | goto out; | ||
74 | r = 0; | ||
75 | break; | ||
76 | } | ||
77 | default: | ||
78 | r = -EINVAL; | ||
79 | } | ||
80 | out: | ||
81 | return r; | ||
82 | } | ||
83 | |||
84 | static __init void kvm_init_msr_list(void) | ||
85 | { | ||
86 | u32 dummy[2]; | ||
87 | unsigned i, j; | ||
88 | |||
89 | for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) { | ||
90 | if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0) | ||
91 | continue; | ||
92 | if (j < i) | ||
93 | msrs_to_save[j] = msrs_to_save[i]; | ||
94 | j++; | ||
95 | } | ||
96 | num_msrs_to_save = j; | ||
97 | } | ||
98 | |||
99 | __init void kvm_arch_init(void) | ||
100 | { | ||
101 | kvm_init_msr_list(); | ||
102 | } | ||