2 * Kernel-based Virtual Machine driver for Linux
4 * derived from drivers/kvm/kvm_main.c
6 * Copyright (C) 2006 Qumranet, Inc.
9 * Avi Kivity <avi@qumranet.com>
10 * Yaniv Kamay <yaniv@qumranet.com>
12 * This work is licensed under the terms of the GNU GPL, version 2. See
13 * the COPYING file in the top-level directory.
19 #include <asm/uaccess.h>
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.
25 * This list is modified at module load time to reflect the
26 * capabilities of the host cpu.
28 static u32 msrs_to_save[] = {
29 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
32 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
34 MSR_IA32_TIME_STAMP_COUNTER,
37 static unsigned num_msrs_to_save;
39 static u32 emulated_msrs[] = {
43 long kvm_arch_dev_ioctl(struct file *filp,
44 unsigned int ioctl, unsigned long arg)
46 void __user *argp = (void __user *)arg;
50 case KVM_GET_MSR_INDEX_LIST: {
51 struct kvm_msr_list __user *user_msr_list = argp;
52 struct kvm_msr_list msr_list;
56 if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list))
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))
63 if (n < num_msrs_to_save)
66 if (copy_to_user(user_msr_list->indices, &msrs_to_save,
67 num_msrs_to_save * sizeof(u32)))
69 if (copy_to_user(user_msr_list->indices
70 + num_msrs_to_save * sizeof(u32),
72 ARRAY_SIZE(emulated_msrs) * sizeof(u32)))
84 static __init void kvm_init_msr_list(void)
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)
93 msrs_to_save[j] = msrs_to_save[i];
99 __init void kvm_arch_init(void)