diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 143 |
1 files changed, 11 insertions, 132 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 5603000573ec..26ca90f74fc7 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
44 | #include <linux/cpumask.h> | 44 | #include <linux/cpumask.h> |
45 | #include <linux/smp.h> | 45 | #include <linux/smp.h> |
46 | #include <linux/anon_inodes.h> | ||
46 | 47 | ||
47 | #include "x86_emulate.h" | 48 | #include "x86_emulate.h" |
48 | #include "segment_descriptor.h" | 49 | #include "segment_descriptor.h" |
@@ -81,8 +82,6 @@ static struct kvm_stats_debugfs_item { | |||
81 | 82 | ||
82 | static struct dentry *debugfs_dir; | 83 | static struct dentry *debugfs_dir; |
83 | 84 | ||
84 | struct vfsmount *kvmfs_mnt; | ||
85 | |||
86 | #define MAX_IO_MSRS 256 | 85 | #define MAX_IO_MSRS 256 |
87 | 86 | ||
88 | #define CR0_RESEVED_BITS 0xffffffff1ffaffc0ULL | 87 | #define CR0_RESEVED_BITS 0xffffffff1ffaffc0ULL |
@@ -104,55 +103,6 @@ struct segment_descriptor_64 { | |||
104 | static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, | 103 | static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, |
105 | unsigned long arg); | 104 | unsigned long arg); |
106 | 105 | ||
107 | static struct inode *kvmfs_inode(struct file_operations *fops) | ||
108 | { | ||
109 | int error = -ENOMEM; | ||
110 | struct inode *inode = new_inode(kvmfs_mnt->mnt_sb); | ||
111 | |||
112 | if (!inode) | ||
113 | goto eexit_1; | ||
114 | |||
115 | inode->i_fop = fops; | ||
116 | |||
117 | /* | ||
118 | * Mark the inode dirty from the very beginning, | ||
119 | * that way it will never be moved to the dirty | ||
120 | * list because mark_inode_dirty() will think | ||
121 | * that it already _is_ on the dirty list. | ||
122 | */ | ||
123 | inode->i_state = I_DIRTY; | ||
124 | inode->i_mode = S_IRUSR | S_IWUSR; | ||
125 | inode->i_uid = current->fsuid; | ||
126 | inode->i_gid = current->fsgid; | ||
127 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
128 | return inode; | ||
129 | |||
130 | eexit_1: | ||
131 | return ERR_PTR(error); | ||
132 | } | ||
133 | |||
134 | static struct file *kvmfs_file(struct inode *inode, void *private_data) | ||
135 | { | ||
136 | struct file *file = get_empty_filp(); | ||
137 | |||
138 | if (!file) | ||
139 | return ERR_PTR(-ENFILE); | ||
140 | |||
141 | file->f_path.mnt = mntget(kvmfs_mnt); | ||
142 | file->f_path.dentry = d_alloc_anon(inode); | ||
143 | if (!file->f_path.dentry) | ||
144 | return ERR_PTR(-ENOMEM); | ||
145 | file->f_mapping = inode->i_mapping; | ||
146 | |||
147 | file->f_pos = 0; | ||
148 | file->f_flags = O_RDWR; | ||
149 | file->f_op = inode->i_fop; | ||
150 | file->f_mode = FMODE_READ | FMODE_WRITE; | ||
151 | file->f_version = 0; | ||
152 | file->private_data = private_data; | ||
153 | return file; | ||
154 | } | ||
155 | |||
156 | unsigned long segment_base(u16 selector) | 106 | unsigned long segment_base(u16 selector) |
157 | { | 107 | { |
158 | struct descriptor_table gdt; | 108 | struct descriptor_table gdt; |
@@ -2413,34 +2363,12 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu) | |||
2413 | struct inode *inode; | 2363 | struct inode *inode; |
2414 | struct file *file; | 2364 | struct file *file; |
2415 | 2365 | ||
2366 | r = anon_inode_getfd(&fd, &inode, &file, | ||
2367 | "kvm-vcpu", &kvm_vcpu_fops, vcpu); | ||
2368 | if (r) | ||
2369 | return r; | ||
2416 | atomic_inc(&vcpu->kvm->filp->f_count); | 2370 | atomic_inc(&vcpu->kvm->filp->f_count); |
2417 | inode = kvmfs_inode(&kvm_vcpu_fops); | ||
2418 | if (IS_ERR(inode)) { | ||
2419 | r = PTR_ERR(inode); | ||
2420 | goto out1; | ||
2421 | } | ||
2422 | |||
2423 | file = kvmfs_file(inode, vcpu); | ||
2424 | if (IS_ERR(file)) { | ||
2425 | r = PTR_ERR(file); | ||
2426 | goto out2; | ||
2427 | } | ||
2428 | |||
2429 | r = get_unused_fd(); | ||
2430 | if (r < 0) | ||
2431 | goto out3; | ||
2432 | fd = r; | ||
2433 | fd_install(fd, file); | ||
2434 | |||
2435 | return fd; | 2371 | return fd; |
2436 | |||
2437 | out3: | ||
2438 | fput(file); | ||
2439 | out2: | ||
2440 | iput(inode); | ||
2441 | out1: | ||
2442 | fput(vcpu->kvm->filp); | ||
2443 | return r; | ||
2444 | } | 2372 | } |
2445 | 2373 | ||
2446 | /* | 2374 | /* |
@@ -2905,41 +2833,18 @@ static int kvm_dev_ioctl_create_vm(void) | |||
2905 | struct file *file; | 2833 | struct file *file; |
2906 | struct kvm *kvm; | 2834 | struct kvm *kvm; |
2907 | 2835 | ||
2908 | inode = kvmfs_inode(&kvm_vm_fops); | ||
2909 | if (IS_ERR(inode)) { | ||
2910 | r = PTR_ERR(inode); | ||
2911 | goto out1; | ||
2912 | } | ||
2913 | |||
2914 | kvm = kvm_create_vm(); | 2836 | kvm = kvm_create_vm(); |
2915 | if (IS_ERR(kvm)) { | 2837 | if (IS_ERR(kvm)) |
2916 | r = PTR_ERR(kvm); | 2838 | return PTR_ERR(kvm); |
2917 | goto out2; | 2839 | r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm); |
2840 | if (r) { | ||
2841 | kvm_destroy_vm(kvm); | ||
2842 | return r; | ||
2918 | } | 2843 | } |
2919 | 2844 | ||
2920 | file = kvmfs_file(inode, kvm); | ||
2921 | if (IS_ERR(file)) { | ||
2922 | r = PTR_ERR(file); | ||
2923 | goto out3; | ||
2924 | } | ||
2925 | kvm->filp = file; | 2845 | kvm->filp = file; |
2926 | 2846 | ||
2927 | r = get_unused_fd(); | ||
2928 | if (r < 0) | ||
2929 | goto out4; | ||
2930 | fd = r; | ||
2931 | fd_install(fd, file); | ||
2932 | |||
2933 | return fd; | 2847 | return fd; |
2934 | |||
2935 | out4: | ||
2936 | fput(file); | ||
2937 | out3: | ||
2938 | kvm_destroy_vm(kvm); | ||
2939 | out2: | ||
2940 | iput(inode); | ||
2941 | out1: | ||
2942 | return r; | ||
2943 | } | 2848 | } |
2944 | 2849 | ||
2945 | static long kvm_dev_ioctl(struct file *filp, | 2850 | static long kvm_dev_ioctl(struct file *filp, |
@@ -3211,18 +3116,6 @@ static struct sys_device kvm_sysdev = { | |||
3211 | 3116 | ||
3212 | hpa_t bad_page_address; | 3117 | hpa_t bad_page_address; |
3213 | 3118 | ||
3214 | static int kvmfs_get_sb(struct file_system_type *fs_type, int flags, | ||
3215 | const char *dev_name, void *data, struct vfsmount *mnt) | ||
3216 | { | ||
3217 | return get_sb_pseudo(fs_type, "kvm:", NULL, KVMFS_SUPER_MAGIC, mnt); | ||
3218 | } | ||
3219 | |||
3220 | static struct file_system_type kvm_fs_type = { | ||
3221 | .name = "kvmfs", | ||
3222 | .get_sb = kvmfs_get_sb, | ||
3223 | .kill_sb = kill_anon_super, | ||
3224 | }; | ||
3225 | |||
3226 | int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) | 3119 | int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) |
3227 | { | 3120 | { |
3228 | int r; | 3121 | int r; |
@@ -3307,14 +3200,6 @@ static __init int kvm_init(void) | |||
3307 | if (r) | 3200 | if (r) |
3308 | goto out4; | 3201 | goto out4; |
3309 | 3202 | ||
3310 | r = register_filesystem(&kvm_fs_type); | ||
3311 | if (r) | ||
3312 | goto out3; | ||
3313 | |||
3314 | kvmfs_mnt = kern_mount(&kvm_fs_type); | ||
3315 | r = PTR_ERR(kvmfs_mnt); | ||
3316 | if (IS_ERR(kvmfs_mnt)) | ||
3317 | goto out2; | ||
3318 | kvm_init_debug(); | 3203 | kvm_init_debug(); |
3319 | 3204 | ||
3320 | kvm_init_msr_list(); | 3205 | kvm_init_msr_list(); |
@@ -3331,10 +3216,6 @@ static __init int kvm_init(void) | |||
3331 | 3216 | ||
3332 | out: | 3217 | out: |
3333 | kvm_exit_debug(); | 3218 | kvm_exit_debug(); |
3334 | mntput(kvmfs_mnt); | ||
3335 | out2: | ||
3336 | unregister_filesystem(&kvm_fs_type); | ||
3337 | out3: | ||
3338 | kvm_mmu_module_exit(); | 3219 | kvm_mmu_module_exit(); |
3339 | out4: | 3220 | out4: |
3340 | return r; | 3221 | return r; |
@@ -3344,8 +3225,6 @@ static __exit void kvm_exit(void) | |||
3344 | { | 3225 | { |
3345 | kvm_exit_debug(); | 3226 | kvm_exit_debug(); |
3346 | __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); | 3227 | __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); |
3347 | mntput(kvmfs_mnt); | ||
3348 | unregister_filesystem(&kvm_fs_type); | ||
3349 | kvm_mmu_module_exit(); | 3228 | kvm_mmu_module_exit(); |
3350 | } | 3229 | } |
3351 | 3230 | ||