Blame view

virt/kvm/kvm_main.c 59.8 KB
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1
2
3
4
5
6
7
  /*
   * Kernel-based Virtual Machine driver for Linux
   *
   * This module enables machines with Intel VT-x extensions to run virtual
   * machines without emulation or binary translation.
   *
   * Copyright (C) 2006 Qumranet, Inc.
9611c1877   Nicolas Kaiser   KVM: fix typo in ...
8
   * Copyright 2010 Red Hat, Inc. and/or its affiliates.
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
9
10
11
12
13
14
15
16
17
   *
   * Authors:
   *   Avi Kivity   <avi@qumranet.com>
   *   Yaniv Kamay  <yaniv@qumranet.com>
   *
   * This work is licensed under the terms of the GNU GPL, version 2.  See
   * the COPYING file in the top-level directory.
   *
   */
e2174021c   Hollis Blanchard   KVM: Portability:...
18
  #include "iodev.h"
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
19

edf884172   Avi Kivity   KVM: Move arch de...
20
  #include <linux/kvm_host.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
21
22
23
  #include <linux/kvm.h>
  #include <linux/module.h>
  #include <linux/errno.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
24
  #include <linux/percpu.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
25
26
27
  #include <linux/mm.h>
  #include <linux/miscdevice.h>
  #include <linux/vmalloc.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
28
  #include <linux/reboot.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
29
30
31
  #include <linux/debugfs.h>
  #include <linux/highmem.h>
  #include <linux/file.h>
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
32
  #include <linux/syscore_ops.h>
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
33
  #include <linux/cpu.h>
e8edc6e03   Alexey Dobriyan   Detach sched.h fr...
34
  #include <linux/sched.h>
d9e368d61   Avi Kivity   KVM: Flush remote...
35
36
  #include <linux/cpumask.h>
  #include <linux/smp.h>
d6d281684   Avi Kivity   KVM: Remove kvmfs...
37
  #include <linux/anon_inodes.h>
04d2cc778   Avi Kivity   KVM: Move main vc...
38
  #include <linux/profile.h>
7aa81cc04   Anthony Liguori   KVM: Refactor hyp...
39
  #include <linux/kvm_para.h>
6fc138d22   Izik Eidus   KVM: Support assi...
40
  #include <linux/pagemap.h>
8d4e1288e   Anthony Liguori   KVM: Allocate use...
41
  #include <linux/mman.h>
35149e212   Anthony Liguori   KVM: MMU: Don't a...
42
  #include <linux/swap.h>
e56d532f2   Sheng Yang   KVM: Device assig...
43
  #include <linux/bitops.h>
547de29e5   Marcelo Tosatti   KVM: protect assi...
44
  #include <linux/spinlock.h>
6ff5894cd   Arnd Bergmann   KVM: Enable 32bit...
45
  #include <linux/compat.h>
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
46
  #include <linux/srcu.h>
8f0b1ab6f   Joerg Roedel   KVM: Introduce kv...
47
  #include <linux/hugetlb.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
48
  #include <linux/slab.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
49

e495606dd   Avi Kivity   KVM: Clean up #in...
50
  #include <asm/processor.h>
e495606dd   Avi Kivity   KVM: Clean up #in...
51
52
  #include <asm/io.h>
  #include <asm/uaccess.h>
3e021bf50   Izik Eidus   KVM: Simplify kvm...
53
  #include <asm/pgtable.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
54

5f94c1741   Laurent Vivier   KVM: Add coalesce...
55
  #include "coalesced_mmio.h"
af585b921   Gleb Natapov   KVM: Halt vcpu if...
56
  #include "async_pf.h"
5f94c1741   Laurent Vivier   KVM: Add coalesce...
57

229456fc3   Marcelo Tosatti   KVM: convert cust...
58
59
  #define CREATE_TRACE_POINTS
  #include <trace/events/kvm.h>
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
60
61
  MODULE_AUTHOR("Qumranet");
  MODULE_LICENSE("GPL");
fa40a8214   Marcelo Tosatti   KVM: switch irq i...
62
63
64
  /*
   * Ordering of locks:
   *
fae3a3536   Sheng Yang   KVM: Fix possible...
65
   * 		kvm->lock --> kvm->slots_lock --> kvm->irq_lock
fa40a8214   Marcelo Tosatti   KVM: switch irq i...
66
   */
e935b8372   Jan Kiszka   KVM: Convert kvm_...
67
  DEFINE_RAW_SPINLOCK(kvm_lock);
e9b11c175   Zhang Xiantao   KVM: Portability:...
68
  LIST_HEAD(vm_list);
133de9021   Avi Kivity   [PATCH] KVM: Add ...
69

7f59f492d   Rusty Russell   KVM: use cpumask_...
70
  static cpumask_var_t cpus_hardware_enabled;
10474ae89   Alexander Graf   KVM: Activate Vir...
71
72
  static int kvm_usage_count = 0;
  static atomic_t hardware_enable_failed;
1b6c01681   Avi Kivity   KVM: Keep track o...
73

c16f862d0   Rusty Russell   KVM: Use kmem cac...
74
75
  struct kmem_cache *kvm_vcpu_cache;
  EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
76

15ad71460   Avi Kivity   KVM: Use the sche...
77
  static __read_mostly struct preempt_ops kvm_preempt_ops;
76f7c8790   Hollis Blanchard   KVM: Rename debug...
78
  struct dentry *kvm_debugfs_dir;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
79

bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
80
81
  static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
  			   unsigned long arg);
1dda606c5   Alexander Graf   KVM: Add compat i...
82
83
84
85
  #ifdef CONFIG_COMPAT
  static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl,
  				  unsigned long arg);
  #endif
10474ae89   Alexander Graf   KVM: Activate Vir...
86
87
  static int hardware_enable_all(void);
  static void hardware_disable_all(void);
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
88

e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
89
  static void kvm_io_bus_destroy(struct kvm_io_bus *bus);
b7c4145ba   Avi Kivity   KVM: Don't spin o...
90
91
  bool kvm_rebooting;
  EXPORT_SYMBOL_GPL(kvm_rebooting);
4ecac3fd6   Avi Kivity   KVM: Handle virtu...
92

54dee9933   Marcelo Tosatti   KVM: VMX: conditi...
93
  static bool largepages_enabled = true;
fa7bff8f8   Gleb Natapov   KVM: define hwpoi...
94
95
  static struct page *hwpoison_page;
  static pfn_t hwpoison_pfn;
bf998156d   Huang Ying   KVM: Avoid killin...
96

fce92dce7   Xiao Guangrong   KVM: MMU: filter ...
97
98
  struct page *fault_page;
  pfn_t fault_pfn;
edba23e51   Gleb Natapov   KVM: Return EFAUL...
99

c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
100
  inline int kvm_is_mmio_pfn(pfn_t pfn)
cbff90a7c   Ben-Ami Yassour   KVM: direct mmio ...
101
  {
fc5659c8c   Joerg Roedel   KVM: MMU: handle ...
102
  	if (pfn_valid(pfn)) {
22e5c47ee   Andrea Arcangeli   thp: add compound...
103
  		int reserved;
936a5fe6e   Andrea Arcangeli   thp: kvm mmu tran...
104
  		struct page *tail = pfn_to_page(pfn);
22e5c47ee   Andrea Arcangeli   thp: add compound...
105
106
  		struct page *head = compound_trans_head(tail);
  		reserved = PageReserved(head);
936a5fe6e   Andrea Arcangeli   thp: kvm mmu tran...
107
  		if (head != tail) {
936a5fe6e   Andrea Arcangeli   thp: kvm mmu tran...
108
  			/*
22e5c47ee   Andrea Arcangeli   thp: add compound...
109
110
111
112
113
114
115
116
  			 * "head" is not a dangling pointer
  			 * (compound_trans_head takes care of that)
  			 * but the hugepage may have been splitted
  			 * from under us (and we may not hold a
  			 * reference count on the head page so it can
  			 * be reused before we run PageReferenced), so
  			 * we've to check PageTail before returning
  			 * what we just read.
936a5fe6e   Andrea Arcangeli   thp: kvm mmu tran...
117
  			 */
22e5c47ee   Andrea Arcangeli   thp: add compound...
118
119
120
  			smp_rmb();
  			if (PageTail(tail))
  				return reserved;
936a5fe6e   Andrea Arcangeli   thp: kvm mmu tran...
121
122
  		}
  		return PageReserved(tail);
fc5659c8c   Joerg Roedel   KVM: MMU: handle ...
123
  	}
cbff90a7c   Ben-Ami Yassour   KVM: direct mmio ...
124
125
126
  
  	return true;
  }
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
127
128
129
  /*
   * Switches to specified vcpu, until a matching vcpu_put()
   */
313a3dc75   Carsten Otte   KVM: Portability:...
130
  void vcpu_load(struct kvm_vcpu *vcpu)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
131
  {
15ad71460   Avi Kivity   KVM: Use the sche...
132
  	int cpu;
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
133
  	mutex_lock(&vcpu->mutex);
34bb10b79   Rik van Riel   KVM: keep track o...
134
135
136
137
138
139
140
141
  	if (unlikely(vcpu->pid != current->pids[PIDTYPE_PID].pid)) {
  		/* The thread running this VCPU changed. */
  		struct pid *oldpid = vcpu->pid;
  		struct pid *newpid = get_task_pid(current, PIDTYPE_PID);
  		rcu_assign_pointer(vcpu->pid, newpid);
  		synchronize_rcu();
  		put_pid(oldpid);
  	}
15ad71460   Avi Kivity   KVM: Use the sche...
142
143
  	cpu = get_cpu();
  	preempt_notifier_register(&vcpu->preempt_notifier);
313a3dc75   Carsten Otte   KVM: Portability:...
144
  	kvm_arch_vcpu_load(vcpu, cpu);
15ad71460   Avi Kivity   KVM: Use the sche...
145
  	put_cpu();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
146
  }
313a3dc75   Carsten Otte   KVM: Portability:...
147
  void vcpu_put(struct kvm_vcpu *vcpu)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
148
  {
15ad71460   Avi Kivity   KVM: Use the sche...
149
  	preempt_disable();
313a3dc75   Carsten Otte   KVM: Portability:...
150
  	kvm_arch_vcpu_put(vcpu);
15ad71460   Avi Kivity   KVM: Use the sche...
151
152
  	preempt_notifier_unregister(&vcpu->preempt_notifier);
  	preempt_enable();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
153
154
  	mutex_unlock(&vcpu->mutex);
  }
d9e368d61   Avi Kivity   KVM: Flush remote...
155
156
  static void ack_flush(void *_completed)
  {
d9e368d61   Avi Kivity   KVM: Flush remote...
157
  }
498468961   Rusty Russell   KVM: Extract core...
158
  static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
d9e368d61   Avi Kivity   KVM: Flush remote...
159
  {
597a5f551   Avi Kivity   KVM: Adjust smp_c...
160
  	int i, cpu, me;
6ef7a1bc4   Rusty Russell   KVM: use modern c...
161
162
  	cpumask_var_t cpus;
  	bool called = true;
d9e368d61   Avi Kivity   KVM: Flush remote...
163
  	struct kvm_vcpu *vcpu;
d9e368d61   Avi Kivity   KVM: Flush remote...
164

79f559977   Li Zefan   cpumask: use zall...
165
  	zalloc_cpumask_var(&cpus, GFP_ATOMIC);
6ef7a1bc4   Rusty Russell   KVM: use modern c...
166

3cba41307   Xiao Guangrong   KVM: make make_al...
167
  	me = get_cpu();
988a2cae6   Gleb Natapov   KVM: Use macro to...
168
  	kvm_for_each_vcpu(i, vcpu, kvm) {
3cba41307   Xiao Guangrong   KVM: make make_al...
169
  		kvm_make_request(req, vcpu);
d9e368d61   Avi Kivity   KVM: Flush remote...
170
  		cpu = vcpu->cpu;
6b7e2d099   Xiao Guangrong   KVM: Add "exiting...
171
172
173
174
175
176
  
  		/* Set ->requests bit before we read ->mode */
  		smp_mb();
  
  		if (cpus != NULL && cpu != -1 && cpu != me &&
  		      kvm_vcpu_exiting_guest_mode(vcpu) != OUTSIDE_GUEST_MODE)
6ef7a1bc4   Rusty Russell   KVM: use modern c...
177
  			cpumask_set_cpu(cpu, cpus);
498468961   Rusty Russell   KVM: Extract core...
178
  	}
6ef7a1bc4   Rusty Russell   KVM: use modern c...
179
180
181
182
183
184
  	if (unlikely(cpus == NULL))
  		smp_call_function_many(cpu_online_mask, ack_flush, NULL, 1);
  	else if (!cpumask_empty(cpus))
  		smp_call_function_many(cpus, ack_flush, NULL, 1);
  	else
  		called = false;
3cba41307   Xiao Guangrong   KVM: make make_al...
185
  	put_cpu();
6ef7a1bc4   Rusty Russell   KVM: use modern c...
186
  	free_cpumask_var(cpus);
498468961   Rusty Russell   KVM: Extract core...
187
  	return called;
d9e368d61   Avi Kivity   KVM: Flush remote...
188
  }
498468961   Rusty Russell   KVM: Extract core...
189
  void kvm_flush_remote_tlbs(struct kvm *kvm)
2e53d63ac   Marcelo Tosatti   KVM: MMU: ignore ...
190
  {
a4ee1ca4a   Xiao Guangrong   KVM: MMU: delay f...
191
192
193
  	int dirty_count = kvm->tlbs_dirty;
  
  	smp_mb();
498468961   Rusty Russell   KVM: Extract core...
194
195
  	if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH))
  		++kvm->stat.remote_tlb_flush;
a4ee1ca4a   Xiao Guangrong   KVM: MMU: delay f...
196
  	cmpxchg(&kvm->tlbs_dirty, dirty_count, 0);
2e53d63ac   Marcelo Tosatti   KVM: MMU: ignore ...
197
  }
498468961   Rusty Russell   KVM: Extract core...
198
199
200
201
  void kvm_reload_remote_mmus(struct kvm *kvm)
  {
  	make_all_cpus_request(kvm, KVM_REQ_MMU_RELOAD);
  }
2e53d63ac   Marcelo Tosatti   KVM: MMU: ignore ...
202

fb3f0f51d   Rusty Russell   KVM: Dynamically ...
203
204
205
206
207
208
209
  int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
  {
  	struct page *page;
  	int r;
  
  	mutex_init(&vcpu->mutex);
  	vcpu->cpu = -1;
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
210
211
  	vcpu->kvm = kvm;
  	vcpu->vcpu_id = id;
34bb10b79   Rik van Riel   KVM: keep track o...
212
  	vcpu->pid = NULL;
b6958ce44   Eddie Dong   KVM: Emulate hlt ...
213
  	init_waitqueue_head(&vcpu->wq);
af585b921   Gleb Natapov   KVM: Halt vcpu if...
214
  	kvm_async_pf_vcpu_init(vcpu);
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
215
216
217
218
219
220
221
  
  	page = alloc_page(GFP_KERNEL | __GFP_ZERO);
  	if (!page) {
  		r = -ENOMEM;
  		goto fail;
  	}
  	vcpu->run = page_address(page);
e9b11c175   Zhang Xiantao   KVM: Portability:...
222
  	r = kvm_arch_vcpu_init(vcpu);
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
223
  	if (r < 0)
e9b11c175   Zhang Xiantao   KVM: Portability:...
224
  		goto fail_free_run;
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
225
  	return 0;
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
226
227
228
  fail_free_run:
  	free_page((unsigned long)vcpu->run);
  fail:
76fafa5e2   Rusty Russell   KVM: Hoist kvm_cr...
229
  	return r;
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
230
231
232
233
234
  }
  EXPORT_SYMBOL_GPL(kvm_vcpu_init);
  
  void kvm_vcpu_uninit(struct kvm_vcpu *vcpu)
  {
34bb10b79   Rik van Riel   KVM: keep track o...
235
  	put_pid(vcpu->pid);
e9b11c175   Zhang Xiantao   KVM: Portability:...
236
  	kvm_arch_vcpu_uninit(vcpu);
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
237
238
239
  	free_page((unsigned long)vcpu->run);
  }
  EXPORT_SYMBOL_GPL(kvm_vcpu_uninit);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
240
241
242
243
244
245
246
247
248
249
250
  #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
  static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn)
  {
  	return container_of(mn, struct kvm, mmu_notifier);
  }
  
  static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
  					     struct mm_struct *mm,
  					     unsigned long address)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
251
  	int need_tlb_flush, idx;
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  
  	/*
  	 * When ->invalidate_page runs, the linux pte has been zapped
  	 * already but the page is still allocated until
  	 * ->invalidate_page returns. So if we increase the sequence
  	 * here the kvm page fault will notice if the spte can't be
  	 * established because the page is going to be freed. If
  	 * instead the kvm page fault establishes the spte before
  	 * ->invalidate_page runs, kvm_unmap_hva will release it
  	 * before returning.
  	 *
  	 * The sequence increase only need to be seen at spin_unlock
  	 * time, and not at spin_lock time.
  	 *
  	 * Increasing the sequence after the spin_unlock would be
  	 * unsafe because the kvm page fault could then establish the
  	 * pte after kvm_unmap_hva returned, without noticing the page
  	 * is going to be freed.
  	 */
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
271
  	idx = srcu_read_lock(&kvm->srcu);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
272
273
  	spin_lock(&kvm->mmu_lock);
  	kvm->mmu_notifier_seq++;
a4ee1ca4a   Xiao Guangrong   KVM: MMU: delay f...
274
  	need_tlb_flush = kvm_unmap_hva(kvm, address) | kvm->tlbs_dirty;
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
275
  	spin_unlock(&kvm->mmu_lock);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
276
  	srcu_read_unlock(&kvm->srcu, idx);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
277
278
279
280
281
282
  
  	/* we've to flush the tlb before the pages can be freed */
  	if (need_tlb_flush)
  		kvm_flush_remote_tlbs(kvm);
  
  }
3da0dd433   Izik Eidus   KVM: add support ...
283
284
285
286
287
288
  static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
  					struct mm_struct *mm,
  					unsigned long address,
  					pte_t pte)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
289
  	int idx;
3da0dd433   Izik Eidus   KVM: add support ...
290

bc6678a33   Marcelo Tosatti   KVM: introduce kv...
291
  	idx = srcu_read_lock(&kvm->srcu);
3da0dd433   Izik Eidus   KVM: add support ...
292
293
294
295
  	spin_lock(&kvm->mmu_lock);
  	kvm->mmu_notifier_seq++;
  	kvm_set_spte_hva(kvm, address, pte);
  	spin_unlock(&kvm->mmu_lock);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
296
  	srcu_read_unlock(&kvm->srcu, idx);
3da0dd433   Izik Eidus   KVM: add support ...
297
  }
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
298
299
300
301
302
303
  static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
  						    struct mm_struct *mm,
  						    unsigned long start,
  						    unsigned long end)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
304
  	int need_tlb_flush = 0, idx;
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
305

bc6678a33   Marcelo Tosatti   KVM: introduce kv...
306
  	idx = srcu_read_lock(&kvm->srcu);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
307
308
309
310
311
312
313
314
315
  	spin_lock(&kvm->mmu_lock);
  	/*
  	 * The count increase must become visible at unlock time as no
  	 * spte can be established without taking the mmu_lock and
  	 * count is also read inside the mmu_lock critical section.
  	 */
  	kvm->mmu_notifier_count++;
  	for (; start < end; start += PAGE_SIZE)
  		need_tlb_flush |= kvm_unmap_hva(kvm, start);
a4ee1ca4a   Xiao Guangrong   KVM: MMU: delay f...
316
  	need_tlb_flush |= kvm->tlbs_dirty;
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
317
  	spin_unlock(&kvm->mmu_lock);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
318
  	srcu_read_unlock(&kvm->srcu, idx);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  
  	/* we've to flush the tlb before the pages can be freed */
  	if (need_tlb_flush)
  		kvm_flush_remote_tlbs(kvm);
  }
  
  static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
  						  struct mm_struct *mm,
  						  unsigned long start,
  						  unsigned long end)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
  
  	spin_lock(&kvm->mmu_lock);
  	/*
  	 * This sequence increase will notify the kvm page fault that
  	 * the page that is going to be mapped in the spte could have
  	 * been freed.
  	 */
  	kvm->mmu_notifier_seq++;
  	/*
  	 * The above sequence increase must be visible before the
  	 * below count decrease but both values are read by the kvm
  	 * page fault under mmu_lock spinlock so we don't need to add
  	 * a smb_wmb() here in between the two.
  	 */
  	kvm->mmu_notifier_count--;
  	spin_unlock(&kvm->mmu_lock);
  
  	BUG_ON(kvm->mmu_notifier_count < 0);
  }
  
  static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
  					      struct mm_struct *mm,
  					      unsigned long address)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
356
  	int young, idx;
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
357

bc6678a33   Marcelo Tosatti   KVM: introduce kv...
358
  	idx = srcu_read_lock(&kvm->srcu);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
359
360
361
  	spin_lock(&kvm->mmu_lock);
  	young = kvm_age_hva(kvm, address);
  	spin_unlock(&kvm->mmu_lock);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
362
  	srcu_read_unlock(&kvm->srcu, idx);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
363
364
365
366
367
368
  
  	if (young)
  		kvm_flush_remote_tlbs(kvm);
  
  	return young;
  }
8ee53820e   Andrea Arcangeli   thp: mmu_notifier...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
  static int kvm_mmu_notifier_test_young(struct mmu_notifier *mn,
  				       struct mm_struct *mm,
  				       unsigned long address)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
  	int young, idx;
  
  	idx = srcu_read_lock(&kvm->srcu);
  	spin_lock(&kvm->mmu_lock);
  	young = kvm_test_age_hva(kvm, address);
  	spin_unlock(&kvm->mmu_lock);
  	srcu_read_unlock(&kvm->srcu, idx);
  
  	return young;
  }
85db06e51   Marcelo Tosatti   KVM: mmu_notifier...
384
385
386
387
  static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
  				     struct mm_struct *mm)
  {
  	struct kvm *kvm = mmu_notifier_to_kvm(mn);
eda2beda8   Lai Jiangshan   KVM: Add missing ...
388
389
390
  	int idx;
  
  	idx = srcu_read_lock(&kvm->srcu);
85db06e51   Marcelo Tosatti   KVM: mmu_notifier...
391
  	kvm_arch_flush_shadow(kvm);
eda2beda8   Lai Jiangshan   KVM: Add missing ...
392
  	srcu_read_unlock(&kvm->srcu, idx);
85db06e51   Marcelo Tosatti   KVM: mmu_notifier...
393
  }
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
394
395
396
397
398
  static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
  	.invalidate_page	= kvm_mmu_notifier_invalidate_page,
  	.invalidate_range_start	= kvm_mmu_notifier_invalidate_range_start,
  	.invalidate_range_end	= kvm_mmu_notifier_invalidate_range_end,
  	.clear_flush_young	= kvm_mmu_notifier_clear_flush_young,
8ee53820e   Andrea Arcangeli   thp: mmu_notifier...
399
  	.test_young		= kvm_mmu_notifier_test_young,
3da0dd433   Izik Eidus   KVM: add support ...
400
  	.change_pte		= kvm_mmu_notifier_change_pte,
85db06e51   Marcelo Tosatti   KVM: mmu_notifier...
401
  	.release		= kvm_mmu_notifier_release,
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
402
  };
4c07b0a4b   Avi Kivity   KVM: Remove ifdef...
403
404
405
406
407
408
409
410
411
412
413
414
415
  
  static int kvm_init_mmu_notifier(struct kvm *kvm)
  {
  	kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
  	return mmu_notifier_register(&kvm->mmu_notifier, current->mm);
  }
  
  #else  /* !(CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER) */
  
  static int kvm_init_mmu_notifier(struct kvm *kvm)
  {
  	return 0;
  }
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
416
  #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
f17abe9a4   Avi Kivity   KVM: Create an in...
417
  static struct kvm *kvm_create_vm(void)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
418
  {
d89f5eff7   Jan Kiszka   KVM: Clean up vm ...
419
420
  	int r, i;
  	struct kvm *kvm = kvm_arch_alloc_vm();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
421

d89f5eff7   Jan Kiszka   KVM: Clean up vm ...
422
423
424
425
426
427
  	if (!kvm)
  		return ERR_PTR(-ENOMEM);
  
  	r = kvm_arch_init_vm(kvm);
  	if (r)
  		goto out_err_nodisable;
10474ae89   Alexander Graf   KVM: Activate Vir...
428
429
430
431
  
  	r = hardware_enable_all();
  	if (r)
  		goto out_err_nodisable;
75858a84a   Avi Kivity   KVM: Interrupt ma...
432
433
  #ifdef CONFIG_HAVE_KVM_IRQCHIP
  	INIT_HLIST_HEAD(&kvm->mask_notifier_list);
136bdfeee   Gleb Natapov   KVM: Move irq ack...
434
  	INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
75858a84a   Avi Kivity   KVM: Interrupt ma...
435
  #endif
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
436

46a26bf55   Marcelo Tosatti   KVM: modify memsl...
437
438
439
  	r = -ENOMEM;
  	kvm->memslots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
  	if (!kvm->memslots)
57e7fbee1   Jan Kiszka   KVM: Refactor src...
440
  		goto out_err_nosrcu;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
441
  	if (init_srcu_struct(&kvm->srcu))
57e7fbee1   Jan Kiszka   KVM: Refactor src...
442
  		goto out_err_nosrcu;
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
443
444
445
  	for (i = 0; i < KVM_NR_BUSES; i++) {
  		kvm->buses[i] = kzalloc(sizeof(struct kvm_io_bus),
  					GFP_KERNEL);
57e7fbee1   Jan Kiszka   KVM: Refactor src...
446
  		if (!kvm->buses[i])
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
447
  			goto out_err;
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
448
  	}
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
449

74b5c5bff   Mike Waychison   KVM: Initialize k...
450
  	spin_lock_init(&kvm->mmu_lock);
6d4e4c4fc   Avi Kivity   KVM: Disallow for...
451
452
  	kvm->mm = current->mm;
  	atomic_inc(&kvm->mm->mm_count);
d34e6b175   Gregory Haskins   KVM: add ioeventf...
453
  	kvm_eventfd_init(kvm);
11ec28047   Shaohua Li   KVM: Convert vm l...
454
  	mutex_init(&kvm->lock);
60eead79a   Marcelo Tosatti   KVM: introduce ir...
455
  	mutex_init(&kvm->irq_lock);
79fac95ec   Marcelo Tosatti   KVM: convert slot...
456
  	mutex_init(&kvm->slots_lock);
d39f13b0d   Izik Eidus   KVM: add vm refco...
457
  	atomic_set(&kvm->users_count, 1);
74b5c5bff   Mike Waychison   KVM: Initialize k...
458
459
460
461
  
  	r = kvm_init_mmu_notifier(kvm);
  	if (r)
  		goto out_err;
e935b8372   Jan Kiszka   KVM: Convert kvm_...
462
  	raw_spin_lock(&kvm_lock);
5e58cfe41   Rusty Russell   KVM: Fix unlikely...
463
  	list_add(&kvm->vm_list, &vm_list);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
464
  	raw_spin_unlock(&kvm_lock);
d89f5eff7   Jan Kiszka   KVM: Clean up vm ...
465

f17abe9a4   Avi Kivity   KVM: Create an in...
466
  	return kvm;
10474ae89   Alexander Graf   KVM: Activate Vir...
467
468
  
  out_err:
57e7fbee1   Jan Kiszka   KVM: Refactor src...
469
470
  	cleanup_srcu_struct(&kvm->srcu);
  out_err_nosrcu:
10474ae89   Alexander Graf   KVM: Activate Vir...
471
472
  	hardware_disable_all();
  out_err_nodisable:
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
473
474
  	for (i = 0; i < KVM_NR_BUSES; i++)
  		kfree(kvm->buses[i]);
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
475
  	kfree(kvm->memslots);
d89f5eff7   Jan Kiszka   KVM: Clean up vm ...
476
  	kvm_arch_free_vm(kvm);
10474ae89   Alexander Graf   KVM: Activate Vir...
477
  	return ERR_PTR(r);
f17abe9a4   Avi Kivity   KVM: Create an in...
478
  }
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
479
480
481
482
  static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
  {
  	if (!memslot->dirty_bitmap)
  		return;
6f9e5c170   Takuya Yoshikawa   KVM: use kmalloc(...
483
484
485
486
  	if (2 * kvm_dirty_bitmap_bytes(memslot) > PAGE_SIZE)
  		vfree(memslot->dirty_bitmap_head);
  	else
  		kfree(memslot->dirty_bitmap_head);
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
487
  	memslot->dirty_bitmap = NULL;
515a01279   Takuya Yoshikawa   KVM: pre-allocate...
488
  	memslot->dirty_bitmap_head = NULL;
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
489
  }
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
490
491
492
493
494
495
  /*
   * Free any memory in @free but not in @dont.
   */
  static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
  				  struct kvm_memory_slot *dont)
  {
ec04b2604   Joerg Roedel   KVM: Prepare mems...
496
  	int i;
290fc38da   Izik Eidus   KVM: Remove the u...
497
498
  	if (!dont || free->rmap != dont->rmap)
  		vfree(free->rmap);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
499
500
  
  	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
501
  		kvm_destroy_dirty_bitmap(free);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
502

ec04b2604   Joerg Roedel   KVM: Prepare mems...
503
504
505
506
507
508
509
  
  	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
  		if (!dont || free->lpage_info[i] != dont->lpage_info[i]) {
  			vfree(free->lpage_info[i]);
  			free->lpage_info[i] = NULL;
  		}
  	}
05da45583   Marcelo Tosatti   KVM: MMU: large p...
510

6aa8b732c   Avi Kivity   [PATCH] kvm: user...
511
  	free->npages = 0;
8d4e1288e   Anthony Liguori   KVM: Allocate use...
512
  	free->rmap = NULL;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
513
  }
d19a9cd27   Zhang Xiantao   KVM: Portability:...
514
  void kvm_free_physmem(struct kvm *kvm)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
515
516
  {
  	int i;
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
517
518
519
520
  	struct kvm_memslots *slots = kvm->memslots;
  
  	for (i = 0; i < slots->nmemslots; ++i)
  		kvm_free_physmem_slot(&slots->memslots[i], NULL);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
521

46a26bf55   Marcelo Tosatti   KVM: modify memsl...
522
  	kfree(kvm->memslots);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
523
  }
f17abe9a4   Avi Kivity   KVM: Create an in...
524
525
  static void kvm_destroy_vm(struct kvm *kvm)
  {
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
526
  	int i;
6d4e4c4fc   Avi Kivity   KVM: Disallow for...
527
  	struct mm_struct *mm = kvm->mm;
ad8ba2cd4   Sheng Yang   KVM: Add kvm_arch...
528
  	kvm_arch_sync_events(kvm);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
529
  	raw_spin_lock(&kvm_lock);
133de9021   Avi Kivity   [PATCH] KVM: Add ...
530
  	list_del(&kvm->vm_list);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
531
  	raw_spin_unlock(&kvm_lock);
399ec807d   Avi Kivity   KVM: Userspace co...
532
  	kvm_free_irq_routing(kvm);
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
533
534
  	for (i = 0; i < KVM_NR_BUSES; i++)
  		kvm_io_bus_destroy(kvm->buses[i]);
980da6ce5   Avi Kivity   KVM: Simplify coa...
535
  	kvm_coalesced_mmio_free(kvm);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
536
537
  #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
  	mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
f00be0cae   Gleb Natapov   KVM: MMU: do not ...
538
539
  #else
  	kvm_arch_flush_shadow(kvm);
e930bffe9   Andrea Arcangeli   KVM: Synchronize ...
540
  #endif
d19a9cd27   Zhang Xiantao   KVM: Portability:...
541
  	kvm_arch_destroy_vm(kvm);
d89f5eff7   Jan Kiszka   KVM: Clean up vm ...
542
543
544
  	kvm_free_physmem(kvm);
  	cleanup_srcu_struct(&kvm->srcu);
  	kvm_arch_free_vm(kvm);
10474ae89   Alexander Graf   KVM: Activate Vir...
545
  	hardware_disable_all();
6d4e4c4fc   Avi Kivity   KVM: Disallow for...
546
  	mmdrop(mm);
f17abe9a4   Avi Kivity   KVM: Create an in...
547
  }
d39f13b0d   Izik Eidus   KVM: add vm refco...
548
549
550
551
552
553
554
555
556
557
558
559
  void kvm_get_kvm(struct kvm *kvm)
  {
  	atomic_inc(&kvm->users_count);
  }
  EXPORT_SYMBOL_GPL(kvm_get_kvm);
  
  void kvm_put_kvm(struct kvm *kvm)
  {
  	if (atomic_dec_and_test(&kvm->users_count))
  		kvm_destroy_vm(kvm);
  }
  EXPORT_SYMBOL_GPL(kvm_put_kvm);
f17abe9a4   Avi Kivity   KVM: Create an in...
560
561
562
  static int kvm_vm_release(struct inode *inode, struct file *filp)
  {
  	struct kvm *kvm = filp->private_data;
721eecbf4   Gregory Haskins   KVM: irqfd
563
  	kvm_irqfd_release(kvm);
d39f13b0d   Izik Eidus   KVM: add vm refco...
564
  	kvm_put_kvm(kvm);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
565
566
  	return 0;
  }
d48ead8b0   Heiko Carstens   KVM: fix build wa...
567
  #ifndef CONFIG_S390
515a01279   Takuya Yoshikawa   KVM: pre-allocate...
568
569
570
571
572
  /*
   * Allocation size is twice as large as the actual dirty bitmap size.
   * This makes it possible to do double buffering: see x86's
   * kvm_vm_ioctl_get_dirty_log().
   */
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
573
574
  static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
  {
515a01279   Takuya Yoshikawa   KVM: pre-allocate...
575
  	unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
576

6f9e5c170   Takuya Yoshikawa   KVM: use kmalloc(...
577
578
579
580
  	if (dirty_bytes > PAGE_SIZE)
  		memslot->dirty_bitmap = vzalloc(dirty_bytes);
  	else
  		memslot->dirty_bitmap = kzalloc(dirty_bytes, GFP_KERNEL);
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
581
582
  	if (!memslot->dirty_bitmap)
  		return -ENOMEM;
515a01279   Takuya Yoshikawa   KVM: pre-allocate...
583
  	memslot->dirty_bitmap_head = memslot->dirty_bitmap;
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
584
585
  	return 0;
  }
d48ead8b0   Heiko Carstens   KVM: fix build wa...
586
  #endif /* !CONFIG_S390 */
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
587

6aa8b732c   Avi Kivity   [PATCH] kvm: user...
588
  /*
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
589
590
591
592
   * Allocate some memory and give it an address in the guest physical address
   * space.
   *
   * Discontiguous memory is allowed, mostly for framebuffers.
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
593
   *
10589a469   Marcelo Tosatti   KVM: MMU: Concurr...
594
   * Must be called holding mmap_sem for write.
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
595
   */
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
596
597
598
  int __kvm_set_memory_region(struct kvm *kvm,
  			    struct kvm_userspace_memory_region *mem,
  			    int user_alloc)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
599
  {
8234b22e1   Avi Kivity   KVM: MMU: Don't f...
600
  	int r;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
601
  	gfn_t base_gfn;
28bcb1121   Heiko Carstens   KVM: fix compile ...
602
603
  	unsigned long npages;
  	unsigned long i;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
604
605
  	struct kvm_memory_slot *memslot;
  	struct kvm_memory_slot old, new;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
606
  	struct kvm_memslots *slots, *old_memslots;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
607
608
609
610
611
612
613
  
  	r = -EINVAL;
  	/* General sanity checks */
  	if (mem->memory_size & (PAGE_SIZE - 1))
  		goto out;
  	if (mem->guest_phys_addr & (PAGE_SIZE - 1))
  		goto out;
fa3d315a4   Takuya Yoshikawa   KVM: Validate use...
614
615
616
  	/* We can read the guest memory with __xxx_user() later on. */
  	if (user_alloc &&
  	    ((mem->userspace_addr & (PAGE_SIZE - 1)) ||
9e3bb6b6f   Heiko Carstens   KVM: add missing ...
617
618
619
  	     !access_ok(VERIFY_WRITE,
  			(void __user *)(unsigned long)mem->userspace_addr,
  			mem->memory_size)))
787498092   Hollis Blanchard   KVM: ensure that ...
620
  		goto out;
e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
621
  	if (mem->slot >= KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
622
623
624
  		goto out;
  	if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
  		goto out;
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
625
  	memslot = &kvm->memslots->memslots[mem->slot];
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
626
627
  	base_gfn = mem->guest_phys_addr >> PAGE_SHIFT;
  	npages = mem->memory_size >> PAGE_SHIFT;
660c22c42   Takuya Yoshikawa   KVM: limit the nu...
628
629
630
  	r = -EINVAL;
  	if (npages > KVM_MEM_MAX_NR_PAGES)
  		goto out;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
631
632
  	if (!npages)
  		mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
633
  	new = old = *memslot;
e36d96f7c   Avi Kivity   KVM: Keep slot ID...
634
  	new.id = mem->slot;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
635
636
637
638
639
640
641
  	new.base_gfn = base_gfn;
  	new.npages = npages;
  	new.flags = mem->flags;
  
  	/* Disallow changing a memory slot's size. */
  	r = -EINVAL;
  	if (npages && old.npages && npages != old.npages)
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
642
  		goto out_free;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
643
644
645
646
  
  	/* Check for overlaps */
  	r = -EEXIST;
  	for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
647
  		struct kvm_memory_slot *s = &kvm->memslots->memslots[i];
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
648

4cd481f68   Jan Kiszka   KVM: Fix overlapp...
649
  		if (s == memslot || !s->npages)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
650
651
652
  			continue;
  		if (!((base_gfn + npages <= s->base_gfn) ||
  		      (base_gfn >= s->base_gfn + s->npages)))
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
653
  			goto out_free;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
654
  	}
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
655

6aa8b732c   Avi Kivity   [PATCH] kvm: user...
656
657
  	/* Free page dirty bitmap if unneeded */
  	if (!(new.flags & KVM_MEM_LOG_DIRTY_PAGES))
8b6d44c7b   Al Viro   [PATCH] kvm: NULL...
658
  		new.dirty_bitmap = NULL;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
659
660
661
662
  
  	r = -ENOMEM;
  
  	/* Allocate if a slot is being created */
eff0114ac   Carsten Otte   KVM: s390: dont a...
663
  #ifndef CONFIG_S390
8d4e1288e   Anthony Liguori   KVM: Allocate use...
664
  	if (npages && !new.rmap) {
265350376   Takuya Yoshikawa   KVM: replace vmal...
665
  		new.rmap = vzalloc(npages * sizeof(*new.rmap));
290fc38da   Izik Eidus   KVM: Remove the u...
666
667
  
  		if (!new.rmap)
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
668
  			goto out_free;
290fc38da   Izik Eidus   KVM: Remove the u...
669

80b14b5b3   Izik Eidus   KVM: Unmap kernel...
670
  		new.user_alloc = user_alloc;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
671
  		new.userspace_addr = mem->userspace_addr;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
672
  	}
ec04b2604   Joerg Roedel   KVM: Prepare mems...
673
674
  	if (!npages)
  		goto skip_lpage;
05da45583   Marcelo Tosatti   KVM: MMU: large p...
675

ec04b2604   Joerg Roedel   KVM: Prepare mems...
676
  	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
28bcb1121   Heiko Carstens   KVM: fix compile ...
677
678
679
  		unsigned long ugfn;
  		unsigned long j;
  		int lpages;
ec04b2604   Joerg Roedel   KVM: Prepare mems...
680
  		int level = i + 2;
05da45583   Marcelo Tosatti   KVM: MMU: large p...
681

ec04b2604   Joerg Roedel   KVM: Prepare mems...
682
683
684
685
686
  		/* Avoid unused variable warning if no large pages */
  		(void)level;
  
  		if (new.lpage_info[i])
  			continue;
828554136   Joerg Roedel   KVM: Remove unnec...
687
688
689
  		lpages = 1 + ((base_gfn + npages - 1)
  			     >> KVM_HPAGE_GFN_SHIFT(level));
  		lpages -= base_gfn >> KVM_HPAGE_GFN_SHIFT(level);
ec04b2604   Joerg Roedel   KVM: Prepare mems...
690

265350376   Takuya Yoshikawa   KVM: replace vmal...
691
  		new.lpage_info[i] = vzalloc(lpages * sizeof(*new.lpage_info[i]));
ec04b2604   Joerg Roedel   KVM: Prepare mems...
692
693
  
  		if (!new.lpage_info[i])
05da45583   Marcelo Tosatti   KVM: MMU: large p...
694
  			goto out_free;
828554136   Joerg Roedel   KVM: Remove unnec...
695
  		if (base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
ec04b2604   Joerg Roedel   KVM: Prepare mems...
696
  			new.lpage_info[i][0].write_count = 1;
828554136   Joerg Roedel   KVM: Remove unnec...
697
  		if ((base_gfn+npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
ec04b2604   Joerg Roedel   KVM: Prepare mems...
698
  			new.lpage_info[i][lpages - 1].write_count = 1;
ac04527f7   Avi Kivity   KVM: Disable larg...
699
700
701
  		ugfn = new.userspace_addr >> PAGE_SHIFT;
  		/*
  		 * If the gfn and userspace address are not aligned wrt each
54dee9933   Marcelo Tosatti   KVM: VMX: conditi...
702
703
  		 * other, or if explicitly asked to, disable large page
  		 * support for this slot
ac04527f7   Avi Kivity   KVM: Disable larg...
704
  		 */
ec04b2604   Joerg Roedel   KVM: Prepare mems...
705
  		if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE(level) - 1) ||
54dee9933   Marcelo Tosatti   KVM: VMX: conditi...
706
  		    !largepages_enabled)
ec04b2604   Joerg Roedel   KVM: Prepare mems...
707
708
  			for (j = 0; j < lpages; ++j)
  				new.lpage_info[i][j].write_count = 1;
05da45583   Marcelo Tosatti   KVM: MMU: large p...
709
  	}
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
710

ec04b2604   Joerg Roedel   KVM: Prepare mems...
711
  skip_lpage:
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
712
713
  	/* Allocate page dirty bitmap if needed */
  	if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
a36a57b1a   Takuya Yoshikawa   KVM: introduce wr...
714
  		if (kvm_create_dirty_bitmap(&new) < 0)
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
715
  			goto out_free;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
716
  		/* destroy any largepage mappings for dirty tracking */
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
717
  	}
3eea8437f   Christian Borntraeger   KVM: s390: Fix me...
718
719
720
721
  #else  /* not defined CONFIG_S390 */
  	new.user_alloc = user_alloc;
  	if (user_alloc)
  		new.userspace_addr = mem->userspace_addr;
eff0114ac   Carsten Otte   KVM: s390: dont a...
722
  #endif /* not defined CONFIG_S390 */
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
723

bc6678a33   Marcelo Tosatti   KVM: introduce kv...
724
725
726
727
728
729
730
731
  	if (!npages) {
  		r = -ENOMEM;
  		slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
  		if (!slots)
  			goto out_free;
  		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
  		if (mem->slot >= slots->nmemslots)
  			slots->nmemslots = mem->slot + 1;
49c7754ce   Gleb Natapov   KVM: Add memory s...
732
  		slots->generation++;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
733
734
735
736
737
738
739
740
741
742
743
744
  		slots->memslots[mem->slot].flags |= KVM_MEMSLOT_INVALID;
  
  		old_memslots = kvm->memslots;
  		rcu_assign_pointer(kvm->memslots, slots);
  		synchronize_srcu_expedited(&kvm->srcu);
  		/* From this point no new shadow pages pointing to a deleted
  		 * memslot will be created.
  		 *
  		 * validation of sp->gfn happens in:
  		 * 	- gfn_to_hva (kvm_read_guest, gfn_to_pfn)
  		 * 	- kvm_is_visible_gfn (mmu_check_roots)
  		 */
34d4cb8fc   Marcelo Tosatti   KVM: MMU: nuke sh...
745
  		kvm_arch_flush_shadow(kvm);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
746
747
  		kfree(old_memslots);
  	}
34d4cb8fc   Marcelo Tosatti   KVM: MMU: nuke sh...
748

f7784b8ec   Marcelo Tosatti   KVM: split kvm_ar...
749
750
751
  	r = kvm_arch_prepare_memory_region(kvm, &new, old, mem, user_alloc);
  	if (r)
  		goto out_free;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
752
753
754
755
756
757
  	/* map the pages in iommu page table */
  	if (npages) {
  		r = kvm_iommu_map_pages(kvm, &new);
  		if (r)
  			goto out_free;
  	}
604b38ac0   Andrea Arcangeli   KVM: Allow browsi...
758

bc6678a33   Marcelo Tosatti   KVM: introduce kv...
759
760
761
762
763
764
765
  	r = -ENOMEM;
  	slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
  	if (!slots)
  		goto out_free;
  	memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
  	if (mem->slot >= slots->nmemslots)
  		slots->nmemslots = mem->slot + 1;
49c7754ce   Gleb Natapov   KVM: Add memory s...
766
  	slots->generation++;
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
767
768
769
770
771
772
773
774
775
776
777
778
779
  
  	/* actual memory is freed via old in kvm_free_physmem_slot below */
  	if (!npages) {
  		new.rmap = NULL;
  		new.dirty_bitmap = NULL;
  		for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i)
  			new.lpage_info[i] = NULL;
  	}
  
  	slots->memslots[mem->slot] = new;
  	old_memslots = kvm->memslots;
  	rcu_assign_pointer(kvm->memslots, slots);
  	synchronize_srcu_expedited(&kvm->srcu);
3ad82a7e8   Zhang Xiantao   KVM: Recalculate ...
780

f7784b8ec   Marcelo Tosatti   KVM: split kvm_ar...
781
  	kvm_arch_commit_memory_region(kvm, mem, old, user_alloc);
82ce2c968   Izik Eidus   KVM: Allow dynami...
782

ce88decff   Xiao Guangrong   KVM: MMU: mmio pa...
783
784
785
786
787
788
  	/*
  	 * If the new memory slot is created, we need to clear all
  	 * mmio sptes.
  	 */
  	if (npages && old.base_gfn != mem->guest_phys_addr >> PAGE_SHIFT)
  		kvm_arch_flush_shadow(kvm);
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
789
790
  	kvm_free_physmem_slot(&old, &new);
  	kfree(old_memslots);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
791
  	return 0;
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
792
  out_free:
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
793
794
795
  	kvm_free_physmem_slot(&new, &old);
  out:
  	return r;
210c7c4d7   Izik Eidus   KVM: Export memor...
796
797
  
  }
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
798
799
800
801
802
803
804
  EXPORT_SYMBOL_GPL(__kvm_set_memory_region);
  
  int kvm_set_memory_region(struct kvm *kvm,
  			  struct kvm_userspace_memory_region *mem,
  			  int user_alloc)
  {
  	int r;
79fac95ec   Marcelo Tosatti   KVM: convert slot...
805
  	mutex_lock(&kvm->slots_lock);
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
806
  	r = __kvm_set_memory_region(kvm, mem, user_alloc);
79fac95ec   Marcelo Tosatti   KVM: convert slot...
807
  	mutex_unlock(&kvm->slots_lock);
f78e0e2ee   Sheng Yang   KVM: VMX: Enable ...
808
809
  	return r;
  }
210c7c4d7   Izik Eidus   KVM: Export memor...
810
  EXPORT_SYMBOL_GPL(kvm_set_memory_region);
1fe779f8e   Carsten Otte   KVM: Portability:...
811
812
813
814
  int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
  				   struct
  				   kvm_userspace_memory_region *mem,
  				   int user_alloc)
210c7c4d7   Izik Eidus   KVM: Export memor...
815
  {
e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
816
817
  	if (mem->slot >= KVM_MEMORY_SLOTS)
  		return -EINVAL;
210c7c4d7   Izik Eidus   KVM: Export memor...
818
  	return kvm_set_memory_region(kvm, mem, user_alloc);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
819
  }
5bb064dcd   Zhang Xiantao   KVM: Portability:...
820
821
  int kvm_get_dirty_log(struct kvm *kvm,
  			struct kvm_dirty_log *log, int *is_dirty)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
822
823
824
  {
  	struct kvm_memory_slot *memslot;
  	int r, i;
87bf6e7de   Takuya Yoshikawa   KVM: fix the hand...
825
  	unsigned long n;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
826
  	unsigned long any = 0;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
827
828
829
  	r = -EINVAL;
  	if (log->slot >= KVM_MEMORY_SLOTS)
  		goto out;
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
830
  	memslot = &kvm->memslots->memslots[log->slot];
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
831
832
833
  	r = -ENOENT;
  	if (!memslot->dirty_bitmap)
  		goto out;
87bf6e7de   Takuya Yoshikawa   KVM: fix the hand...
834
  	n = kvm_dirty_bitmap_bytes(memslot);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
835

cd1a4a982   Uri Lublin   KVM: Fix dirty pa...
836
  	for (i = 0; !any && i < n/sizeof(long); ++i)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
837
838
839
840
841
  		any = memslot->dirty_bitmap[i];
  
  	r = -EFAULT;
  	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
  		goto out;
5bb064dcd   Zhang Xiantao   KVM: Portability:...
842
843
  	if (any)
  		*is_dirty = 1;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
844
845
  
  	r = 0;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
846
  out:
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
847
848
  	return r;
  }
54dee9933   Marcelo Tosatti   KVM: VMX: conditi...
849
850
851
852
853
  void kvm_disable_largepages(void)
  {
  	largepages_enabled = false;
  }
  EXPORT_SYMBOL_GPL(kvm_disable_largepages);
cea7bb212   Izik Eidus   KVM: MMU: Make gf...
854
855
  int is_error_page(struct page *page)
  {
edba23e51   Gleb Natapov   KVM: Return EFAUL...
856
  	return page == bad_page || page == hwpoison_page || page == fault_page;
cea7bb212   Izik Eidus   KVM: MMU: Make gf...
857
858
  }
  EXPORT_SYMBOL_GPL(is_error_page);
35149e212   Anthony Liguori   KVM: MMU: Don't a...
859
860
  int is_error_pfn(pfn_t pfn)
  {
edba23e51   Gleb Natapov   KVM: Return EFAUL...
861
  	return pfn == bad_pfn || pfn == hwpoison_pfn || pfn == fault_pfn;
35149e212   Anthony Liguori   KVM: MMU: Don't a...
862
863
  }
  EXPORT_SYMBOL_GPL(is_error_pfn);
bf998156d   Huang Ying   KVM: Avoid killin...
864
865
866
867
868
  int is_hwpoison_pfn(pfn_t pfn)
  {
  	return pfn == hwpoison_pfn;
  }
  EXPORT_SYMBOL_GPL(is_hwpoison_pfn);
edba23e51   Gleb Natapov   KVM: Return EFAUL...
869
870
871
872
873
  int is_fault_pfn(pfn_t pfn)
  {
  	return pfn == fault_pfn;
  }
  EXPORT_SYMBOL_GPL(is_fault_pfn);
fce92dce7   Xiao Guangrong   KVM: MMU: filter ...
874
875
876
877
878
879
880
881
882
883
884
  int is_noslot_pfn(pfn_t pfn)
  {
  	return pfn == bad_pfn;
  }
  EXPORT_SYMBOL_GPL(is_noslot_pfn);
  
  int is_invalid_pfn(pfn_t pfn)
  {
  	return pfn == hwpoison_pfn || pfn == fault_pfn;
  }
  EXPORT_SYMBOL_GPL(is_invalid_pfn);
f9d46eb0e   Izik Eidus   KVM: add kvm_is_e...
885
886
887
888
889
890
891
892
893
894
  static inline unsigned long bad_hva(void)
  {
  	return PAGE_OFFSET;
  }
  
  int kvm_is_error_hva(unsigned long addr)
  {
  	return addr == bad_hva();
  }
  EXPORT_SYMBOL_GPL(kvm_is_error_hva);
49c7754ce   Gleb Natapov   KVM: Add memory s...
895
896
  static struct kvm_memory_slot *__gfn_to_memslot(struct kvm_memslots *slots,
  						gfn_t gfn)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
897
898
  {
  	int i;
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
899
900
  	for (i = 0; i < slots->nmemslots; ++i) {
  		struct kvm_memory_slot *memslot = &slots->memslots[i];
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
901
902
903
904
905
  
  		if (gfn >= memslot->base_gfn
  		    && gfn < memslot->base_gfn + memslot->npages)
  			return memslot;
  	}
8b6d44c7b   Al Viro   [PATCH] kvm: NULL...
906
  	return NULL;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
907
  }
49c7754ce   Gleb Natapov   KVM: Add memory s...
908
909
910
911
912
  
  struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
  {
  	return __gfn_to_memslot(kvm_memslots(kvm), gfn);
  }
a1f4d3950   Avi Kivity   KVM: Remove memor...
913
  EXPORT_SYMBOL_GPL(gfn_to_memslot);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
914

e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
915
916
917
  int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
  {
  	int i;
90d83dc3d   Lai Jiangshan   KVM: use the corr...
918
  	struct kvm_memslots *slots = kvm_memslots(kvm);
e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
919

e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
920
  	for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
46a26bf55   Marcelo Tosatti   KVM: modify memsl...
921
  		struct kvm_memory_slot *memslot = &slots->memslots[i];
e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
922

bc6678a33   Marcelo Tosatti   KVM: introduce kv...
923
924
  		if (memslot->flags & KVM_MEMSLOT_INVALID)
  			continue;
e0d62c7f4   Izik Eidus   KVM: Add kernel-i...
925
926
927
928
929
930
931
  		if (gfn >= memslot->base_gfn
  		    && gfn < memslot->base_gfn + memslot->npages)
  			return 1;
  	}
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_is_visible_gfn);
8f0b1ab6f   Joerg Roedel   KVM: Introduce kv...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
  unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn)
  {
  	struct vm_area_struct *vma;
  	unsigned long addr, size;
  
  	size = PAGE_SIZE;
  
  	addr = gfn_to_hva(kvm, gfn);
  	if (kvm_is_error_hva(addr))
  		return PAGE_SIZE;
  
  	down_read(&current->mm->mmap_sem);
  	vma = find_vma(current->mm, addr);
  	if (!vma)
  		goto out;
  
  	size = vma_kernel_pagesize(vma);
  
  out:
  	up_read(&current->mm->mmap_sem);
  
  	return size;
  }
49c7754ce   Gleb Natapov   KVM: Add memory s...
955
  static unsigned long gfn_to_hva_many(struct kvm_memory_slot *slot, gfn_t gfn,
48987781e   Xiao Guangrong   KVM: MMU: introdu...
956
  				     gfn_t *nr_pages)
539cb6608   Izik Eidus   KVM: introduce gf...
957
  {
bc6678a33   Marcelo Tosatti   KVM: introduce kv...
958
  	if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
539cb6608   Izik Eidus   KVM: introduce gf...
959
  		return bad_hva();
48987781e   Xiao Guangrong   KVM: MMU: introdu...
960
961
962
  
  	if (nr_pages)
  		*nr_pages = slot->npages - (gfn - slot->base_gfn);
f5c980317   Takuya Yoshikawa   KVM: update gfn_t...
963
  	return gfn_to_hva_memslot(slot, gfn);
539cb6608   Izik Eidus   KVM: introduce gf...
964
  }
48987781e   Xiao Guangrong   KVM: MMU: introdu...
965
966
967
  
  unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
  {
49c7754ce   Gleb Natapov   KVM: Add memory s...
968
  	return gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, NULL);
48987781e   Xiao Guangrong   KVM: MMU: introdu...
969
  }
0d1502989   Sheng Yang   KVM: Export neces...
970
  EXPORT_SYMBOL_GPL(gfn_to_hva);
539cb6608   Izik Eidus   KVM: introduce gf...
971

8030089f9   Gleb Natapov   KVM: improve hva_...
972
973
974
975
976
  static pfn_t get_fault_pfn(void)
  {
  	get_page(fault_page);
  	return fault_pfn;
  }
0857b9e95   Gleb Natapov   KVM: Enable async...
977
978
979
980
981
982
983
984
985
986
  int get_user_page_nowait(struct task_struct *tsk, struct mm_struct *mm,
  	unsigned long start, int write, struct page **page)
  {
  	int flags = FOLL_TOUCH | FOLL_NOWAIT | FOLL_HWPOISON | FOLL_GET;
  
  	if (write)
  		flags |= FOLL_WRITE;
  
  	return __get_user_pages(tsk, mm, start, 1, flags, page, NULL, NULL);
  }
fafc3dbaa   Huang Ying   KVM: Replace is_h...
987
988
989
990
991
992
993
994
  static inline int check_user_page_hwpoison(unsigned long addr)
  {
  	int rc, flags = FOLL_TOUCH | FOLL_HWPOISON | FOLL_WRITE;
  
  	rc = __get_user_pages(current, current->mm, addr, 1,
  			      flags, NULL, NULL, NULL);
  	return rc == -EHWPOISON;
  }
af585b921   Gleb Natapov   KVM: Halt vcpu if...
995
  static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic,
612819c3c   Marcelo Tosatti   KVM: propagate fa...
996
  			bool *async, bool write_fault, bool *writable)
954bbbc23   Avi Kivity   KVM: Simply gfn_t...
997
  {
8d4e1288e   Anthony Liguori   KVM: Allocate use...
998
  	struct page *page[1];
af585b921   Gleb Natapov   KVM: Halt vcpu if...
999
  	int npages = 0;
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1000
  	pfn_t pfn;
954bbbc23   Avi Kivity   KVM: Simply gfn_t...
1001

af585b921   Gleb Natapov   KVM: Halt vcpu if...
1002
1003
  	/* we can do it either atomically or asynchronously, not both */
  	BUG_ON(atomic && async);
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1004
1005
1006
1007
  	BUG_ON(!write_fault && !writable);
  
  	if (writable)
  		*writable = true;
af585b921   Gleb Natapov   KVM: Halt vcpu if...
1008
  	if (atomic || async)
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1009
  		npages = __get_user_pages_fast(addr, 1, 1, page);
af585b921   Gleb Natapov   KVM: Halt vcpu if...
1010
1011
  
  	if (unlikely(npages != 1) && !atomic) {
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1012
  		might_sleep();
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1013
1014
1015
  
  		if (writable)
  			*writable = write_fault;
0857b9e95   Gleb Natapov   KVM: Enable async...
1016
1017
1018
1019
1020
1021
1022
1023
  		if (async) {
  			down_read(&current->mm->mmap_sem);
  			npages = get_user_page_nowait(current, current->mm,
  						     addr, write_fault, page);
  			up_read(&current->mm->mmap_sem);
  		} else
  			npages = get_user_pages_fast(addr, 1, write_fault,
  						     page);
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
  
  		/* map read fault as writable if possible */
  		if (unlikely(!write_fault) && npages == 1) {
  			struct page *wpage[1];
  
  			npages = __get_user_pages_fast(addr, 1, 1, wpage);
  			if (npages == 1) {
  				*writable = true;
  				put_page(page[0]);
  				page[0] = wpage[0];
  			}
  			npages = 1;
  		}
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1037
  	}
539cb6608   Izik Eidus   KVM: introduce gf...
1038

2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1039
1040
  	if (unlikely(npages != 1)) {
  		struct vm_area_struct *vma;
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1041
  		if (atomic)
8030089f9   Gleb Natapov   KVM: improve hva_...
1042
  			return get_fault_pfn();
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1043

bbeb34062   Huang Ying   KVM: Fix a race c...
1044
  		down_read(&current->mm->mmap_sem);
0857b9e95   Gleb Natapov   KVM: Enable async...
1045
1046
  		if (npages == -EHWPOISON ||
  			(!async && check_user_page_hwpoison(addr))) {
bbeb34062   Huang Ying   KVM: Fix a race c...
1047
  			up_read(&current->mm->mmap_sem);
bf998156d   Huang Ying   KVM: Avoid killin...
1048
1049
1050
  			get_page(hwpoison_page);
  			return page_to_pfn(hwpoison_page);
  		}
8030089f9   Gleb Natapov   KVM: improve hva_...
1051
  		vma = find_vma_intersection(current->mm, addr, addr+1);
4c2155ce8   Marcelo Tosatti   KVM: switch to ge...
1052

8030089f9   Gleb Natapov   KVM: improve hva_...
1053
1054
1055
1056
1057
1058
1059
1060
  		if (vma == NULL)
  			pfn = get_fault_pfn();
  		else if ((vma->vm_flags & VM_PFNMAP)) {
  			pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) +
  				vma->vm_pgoff;
  			BUG_ON(!kvm_is_mmio_pfn(pfn));
  		} else {
  			if (async && (vma->vm_flags & VM_WRITE))
af585b921   Gleb Natapov   KVM: Halt vcpu if...
1061
  				*async = true;
8030089f9   Gleb Natapov   KVM: improve hva_...
1062
  			pfn = get_fault_pfn();
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1063
  		}
4c2155ce8   Marcelo Tosatti   KVM: switch to ge...
1064
  		up_read(&current->mm->mmap_sem);
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1065
1066
  	} else
  		pfn = page_to_pfn(page[0]);
8d4e1288e   Anthony Liguori   KVM: Allocate use...
1067

2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1068
  	return pfn;
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1069
  }
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1070
1071
  pfn_t hva_to_pfn_atomic(struct kvm *kvm, unsigned long addr)
  {
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1072
  	return hva_to_pfn(kvm, addr, true, NULL, true, NULL);
887c08ac1   Xiao Guangrong   KVM: MMU: introdu...
1073
1074
  }
  EXPORT_SYMBOL_GPL(hva_to_pfn_atomic);
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1075
1076
  static pfn_t __gfn_to_pfn(struct kvm *kvm, gfn_t gfn, bool atomic, bool *async,
  			  bool write_fault, bool *writable)
506f0d6f9   Marcelo Tosatti   KVM: introduce gf...
1077
1078
  {
  	unsigned long addr;
af585b921   Gleb Natapov   KVM: Halt vcpu if...
1079
1080
  	if (async)
  		*async = false;
506f0d6f9   Marcelo Tosatti   KVM: introduce gf...
1081
1082
1083
1084
1085
  	addr = gfn_to_hva(kvm, gfn);
  	if (kvm_is_error_hva(addr)) {
  		get_page(bad_page);
  		return page_to_pfn(bad_page);
  	}
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1086
  	return hva_to_pfn(kvm, addr, atomic, async, write_fault, writable);
365fb3fdf   Xiao Guangrong   KVM: MMU: rewrite...
1087
1088
1089
1090
  }
  
  pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn)
  {
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1091
  	return __gfn_to_pfn(kvm, gfn, true, NULL, true, NULL);
365fb3fdf   Xiao Guangrong   KVM: MMU: rewrite...
1092
1093
  }
  EXPORT_SYMBOL_GPL(gfn_to_pfn_atomic);
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1094
1095
  pfn_t gfn_to_pfn_async(struct kvm *kvm, gfn_t gfn, bool *async,
  		       bool write_fault, bool *writable)
af585b921   Gleb Natapov   KVM: Halt vcpu if...
1096
  {
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1097
  	return __gfn_to_pfn(kvm, gfn, false, async, write_fault, writable);
af585b921   Gleb Natapov   KVM: Halt vcpu if...
1098
1099
  }
  EXPORT_SYMBOL_GPL(gfn_to_pfn_async);
365fb3fdf   Xiao Guangrong   KVM: MMU: rewrite...
1100
1101
  pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
  {
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1102
  	return __gfn_to_pfn(kvm, gfn, false, NULL, true, NULL);
506f0d6f9   Marcelo Tosatti   KVM: introduce gf...
1103
  }
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1104
  EXPORT_SYMBOL_GPL(gfn_to_pfn);
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1105
1106
1107
1108
1109
1110
  pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
  		      bool *writable)
  {
  	return __gfn_to_pfn(kvm, gfn, false, NULL, write_fault, writable);
  }
  EXPORT_SYMBOL_GPL(gfn_to_pfn_prot);
506f0d6f9   Marcelo Tosatti   KVM: introduce gf...
1111
1112
1113
1114
  pfn_t gfn_to_pfn_memslot(struct kvm *kvm,
  			 struct kvm_memory_slot *slot, gfn_t gfn)
  {
  	unsigned long addr = gfn_to_hva_memslot(slot, gfn);
612819c3c   Marcelo Tosatti   KVM: propagate fa...
1115
  	return hva_to_pfn(kvm, addr, false, NULL, true, NULL);
506f0d6f9   Marcelo Tosatti   KVM: introduce gf...
1116
  }
48987781e   Xiao Guangrong   KVM: MMU: introdu...
1117
1118
1119
1120
1121
  int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
  								  int nr_pages)
  {
  	unsigned long addr;
  	gfn_t entry;
49c7754ce   Gleb Natapov   KVM: Add memory s...
1122
  	addr = gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, &entry);
48987781e   Xiao Guangrong   KVM: MMU: introdu...
1123
1124
1125
1126
1127
1128
1129
1130
1131
  	if (kvm_is_error_hva(addr))
  		return -1;
  
  	if (entry < nr_pages)
  		return 0;
  
  	return __get_user_pages_fast(addr, nr_pages, 1, pages);
  }
  EXPORT_SYMBOL_GPL(gfn_to_page_many_atomic);
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1132
1133
  struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
  {
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1134
1135
1136
  	pfn_t pfn;
  
  	pfn = gfn_to_pfn(kvm, gfn);
c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
1137
  	if (!kvm_is_mmio_pfn(pfn))
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1138
  		return pfn_to_page(pfn);
c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
1139
  	WARN_ON(kvm_is_mmio_pfn(pfn));
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1140
1141
1142
  
  	get_page(bad_page);
  	return bad_page;
954bbbc23   Avi Kivity   KVM: Simply gfn_t...
1143
  }
aab61cc0d   Anthony Liguori   KVM: Fix gfn_to_p...
1144

954bbbc23   Avi Kivity   KVM: Simply gfn_t...
1145
  EXPORT_SYMBOL_GPL(gfn_to_page);
b4231d618   Izik Eidus   KVM: MMU: Selecti...
1146
1147
  void kvm_release_page_clean(struct page *page)
  {
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1148
  	kvm_release_pfn_clean(page_to_pfn(page));
b4231d618   Izik Eidus   KVM: MMU: Selecti...
1149
1150
  }
  EXPORT_SYMBOL_GPL(kvm_release_page_clean);
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1151
1152
  void kvm_release_pfn_clean(pfn_t pfn)
  {
c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
1153
  	if (!kvm_is_mmio_pfn(pfn))
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1154
  		put_page(pfn_to_page(pfn));
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1155
1156
  }
  EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);
b4231d618   Izik Eidus   KVM: MMU: Selecti...
1157
  void kvm_release_page_dirty(struct page *page)
8a7ae055f   Izik Eidus   KVM: MMU: Partial...
1158
  {
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
  	kvm_release_pfn_dirty(page_to_pfn(page));
  }
  EXPORT_SYMBOL_GPL(kvm_release_page_dirty);
  
  void kvm_release_pfn_dirty(pfn_t pfn)
  {
  	kvm_set_pfn_dirty(pfn);
  	kvm_release_pfn_clean(pfn);
  }
  EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
  
  void kvm_set_page_dirty(struct page *page)
  {
  	kvm_set_pfn_dirty(page_to_pfn(page));
  }
  EXPORT_SYMBOL_GPL(kvm_set_page_dirty);
  
  void kvm_set_pfn_dirty(pfn_t pfn)
  {
c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
1178
  	if (!kvm_is_mmio_pfn(pfn)) {
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1179
1180
1181
1182
  		struct page *page = pfn_to_page(pfn);
  		if (!PageReserved(page))
  			SetPageDirty(page);
  	}
8a7ae055f   Izik Eidus   KVM: MMU: Partial...
1183
  }
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1184
1185
1186
1187
  EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
  
  void kvm_set_pfn_accessed(pfn_t pfn)
  {
c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
1188
  	if (!kvm_is_mmio_pfn(pfn))
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1189
  		mark_page_accessed(pfn_to_page(pfn));
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1190
1191
1192
1193
1194
  }
  EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
  
  void kvm_get_pfn(pfn_t pfn)
  {
c77fb9dc7   Xiantao Zhang   KVM: Change is_mm...
1195
  	if (!kvm_is_mmio_pfn(pfn))
2e2e3738a   Anthony Liguori   KVM: Handle vma r...
1196
  		get_page(pfn_to_page(pfn));
35149e212   Anthony Liguori   KVM: MMU: Don't a...
1197
1198
  }
  EXPORT_SYMBOL_GPL(kvm_get_pfn);
8a7ae055f   Izik Eidus   KVM: MMU: Partial...
1199

195aefde9   Izik Eidus   KVM: Add general ...
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
  static int next_segment(unsigned long len, int offset)
  {
  	if (len > PAGE_SIZE - offset)
  		return PAGE_SIZE - offset;
  	else
  		return len;
  }
  
  int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset,
  			int len)
  {
e0506bcba   Izik Eidus   KVM: Change kvm_{...
1211
1212
  	int r;
  	unsigned long addr;
195aefde9   Izik Eidus   KVM: Add general ...
1213

e0506bcba   Izik Eidus   KVM: Change kvm_{...
1214
1215
1216
  	addr = gfn_to_hva(kvm, gfn);
  	if (kvm_is_error_hva(addr))
  		return -EFAULT;
fa3d315a4   Takuya Yoshikawa   KVM: Validate use...
1217
  	r = __copy_from_user(data, (void __user *)addr + offset, len);
e0506bcba   Izik Eidus   KVM: Change kvm_{...
1218
  	if (r)
195aefde9   Izik Eidus   KVM: Add general ...
1219
  		return -EFAULT;
195aefde9   Izik Eidus   KVM: Add general ...
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_read_guest_page);
  
  int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len)
  {
  	gfn_t gfn = gpa >> PAGE_SHIFT;
  	int seg;
  	int offset = offset_in_page(gpa);
  	int ret;
  
  	while ((seg = next_segment(len, offset)) != 0) {
  		ret = kvm_read_guest_page(kvm, gfn, data, offset, seg);
  		if (ret < 0)
  			return ret;
  		offset = 0;
  		len -= seg;
  		data += seg;
  		++gfn;
  	}
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_read_guest);
7ec545882   Marcelo Tosatti   KVM: Add kvm_read...
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
  int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data,
  			  unsigned long len)
  {
  	int r;
  	unsigned long addr;
  	gfn_t gfn = gpa >> PAGE_SHIFT;
  	int offset = offset_in_page(gpa);
  
  	addr = gfn_to_hva(kvm, gfn);
  	if (kvm_is_error_hva(addr))
  		return -EFAULT;
0aac03f07   Andrea Arcangeli   KVM: Disable page...
1254
  	pagefault_disable();
7ec545882   Marcelo Tosatti   KVM: Add kvm_read...
1255
  	r = __copy_from_user_inatomic(data, (void __user *)addr + offset, len);
0aac03f07   Andrea Arcangeli   KVM: Disable page...
1256
  	pagefault_enable();
7ec545882   Marcelo Tosatti   KVM: Add kvm_read...
1257
1258
1259
1260
1261
  	if (r)
  		return -EFAULT;
  	return 0;
  }
  EXPORT_SYMBOL(kvm_read_guest_atomic);
195aefde9   Izik Eidus   KVM: Add general ...
1262
1263
1264
  int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data,
  			 int offset, int len)
  {
e0506bcba   Izik Eidus   KVM: Change kvm_{...
1265
1266
  	int r;
  	unsigned long addr;
195aefde9   Izik Eidus   KVM: Add general ...
1267

e0506bcba   Izik Eidus   KVM: Change kvm_{...
1268
1269
1270
  	addr = gfn_to_hva(kvm, gfn);
  	if (kvm_is_error_hva(addr))
  		return -EFAULT;
8b0cedff0   Xiao Guangrong   KVM: use __copy_t...
1271
  	r = __copy_to_user((void __user *)addr + offset, data, len);
e0506bcba   Izik Eidus   KVM: Change kvm_{...
1272
  	if (r)
195aefde9   Izik Eidus   KVM: Add general ...
1273
  		return -EFAULT;
195aefde9   Izik Eidus   KVM: Add general ...
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
  	mark_page_dirty(kvm, gfn);
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_write_guest_page);
  
  int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
  		    unsigned long len)
  {
  	gfn_t gfn = gpa >> PAGE_SHIFT;
  	int seg;
  	int offset = offset_in_page(gpa);
  	int ret;
  
  	while ((seg = next_segment(len, offset)) != 0) {
  		ret = kvm_write_guest_page(kvm, gfn, data, offset, seg);
  		if (ret < 0)
  			return ret;
  		offset = 0;
  		len -= seg;
  		data += seg;
  		++gfn;
  	}
  	return 0;
  }
49c7754ce   Gleb Natapov   KVM: Add memory s...
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
  int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
  			      gpa_t gpa)
  {
  	struct kvm_memslots *slots = kvm_memslots(kvm);
  	int offset = offset_in_page(gpa);
  	gfn_t gfn = gpa >> PAGE_SHIFT;
  
  	ghc->gpa = gpa;
  	ghc->generation = slots->generation;
  	ghc->memslot = __gfn_to_memslot(slots, gfn);
  	ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL);
  	if (!kvm_is_error_hva(ghc->hva))
  		ghc->hva += offset;
  	else
  		return -EFAULT;
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
  
  int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
  			   void *data, unsigned long len)
  {
  	struct kvm_memslots *slots = kvm_memslots(kvm);
  	int r;
  
  	if (slots->generation != ghc->generation)
  		kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
  
  	if (kvm_is_error_hva(ghc->hva))
  		return -EFAULT;
8b0cedff0   Xiao Guangrong   KVM: use __copy_t...
1329
  	r = __copy_to_user((void __user *)ghc->hva, data, len);
49c7754ce   Gleb Natapov   KVM: Add memory s...
1330
1331
1332
1333
1334
1335
1336
  	if (r)
  		return -EFAULT;
  	mark_page_dirty_in_slot(kvm, ghc->memslot, ghc->gpa >> PAGE_SHIFT);
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_write_guest_cached);
e03b644fe   Gleb Natapov   KVM: introduce kv...
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
  int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
  			   void *data, unsigned long len)
  {
  	struct kvm_memslots *slots = kvm_memslots(kvm);
  	int r;
  
  	if (slots->generation != ghc->generation)
  		kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
  
  	if (kvm_is_error_hva(ghc->hva))
  		return -EFAULT;
  
  	r = __copy_from_user(data, (void __user *)ghc->hva, len);
  	if (r)
  		return -EFAULT;
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_read_guest_cached);
195aefde9   Izik Eidus   KVM: Add general ...
1356
1357
  int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len)
  {
3bcc8a8c6   Heiko Carstens   KVM: add cast wit...
1358
1359
  	return kvm_write_guest_page(kvm, gfn, (const void *) empty_zero_page,
  				    offset, len);
195aefde9   Izik Eidus   KVM: Add general ...
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
  }
  EXPORT_SYMBOL_GPL(kvm_clear_guest_page);
  
  int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
  {
  	gfn_t gfn = gpa >> PAGE_SHIFT;
  	int seg;
  	int offset = offset_in_page(gpa);
  	int ret;
  
          while ((seg = next_segment(len, offset)) != 0) {
  		ret = kvm_clear_guest_page(kvm, gfn, offset, seg);
  		if (ret < 0)
  			return ret;
  		offset = 0;
  		len -= seg;
  		++gfn;
  	}
  	return 0;
  }
  EXPORT_SYMBOL_GPL(kvm_clear_guest);
49c7754ce   Gleb Natapov   KVM: Add memory s...
1381
1382
  void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
  			     gfn_t gfn)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1383
  {
7e9d619d2   Rusty Russell   KVM: Cleanup mark...
1384
1385
  	if (memslot && memslot->dirty_bitmap) {
  		unsigned long rel_gfn = gfn - memslot->base_gfn;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1386

cd7e48c5d   Akinobu Mita   kvm: use little-e...
1387
  		__set_bit_le(rel_gfn, memslot->dirty_bitmap);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1388
1389
  	}
  }
49c7754ce   Gleb Natapov   KVM: Add memory s...
1390
1391
1392
1393
1394
1395
1396
  void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
  {
  	struct kvm_memory_slot *memslot;
  
  	memslot = gfn_to_memslot(kvm, gfn);
  	mark_page_dirty_in_slot(kvm, memslot, gfn);
  }
b6958ce44   Eddie Dong   KVM: Emulate hlt ...
1397
1398
1399
  /*
   * The vCPU has executed a HLT instruction with in-kernel mode enabled.
   */
8776e5194   Hollis Blanchard   KVM: Portability:...
1400
  void kvm_vcpu_block(struct kvm_vcpu *vcpu)
d3bef15f8   Avi Kivity   KVM: Move duplica...
1401
  {
e5c239cfd   Marcelo Tosatti   KVM: Fix kvm_vcpu...
1402
1403
1404
1405
  	DEFINE_WAIT(wait);
  
  	for (;;) {
  		prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
a1b37100d   Gleb Natapov   KVM: Reduce runna...
1406
  		if (kvm_arch_vcpu_runnable(vcpu)) {
a8eeb04a4   Avi Kivity   KVM: Add mini-API...
1407
  			kvm_make_request(KVM_REQ_UNHALT, vcpu);
e5c239cfd   Marcelo Tosatti   KVM: Fix kvm_vcpu...
1408
  			break;
d76901750   Marcelo Tosatti   KVM: x86: do not ...
1409
  		}
09cec7548   Gleb Natapov   KVM: Timer event ...
1410
1411
  		if (kvm_cpu_has_pending_timer(vcpu))
  			break;
e5c239cfd   Marcelo Tosatti   KVM: Fix kvm_vcpu...
1412
1413
  		if (signal_pending(current))
  			break;
b6958ce44   Eddie Dong   KVM: Emulate hlt ...
1414
  		schedule();
b6958ce44   Eddie Dong   KVM: Emulate hlt ...
1415
  	}
d3bef15f8   Avi Kivity   KVM: Move duplica...
1416

e5c239cfd   Marcelo Tosatti   KVM: Fix kvm_vcpu...
1417
  	finish_wait(&vcpu->wq, &wait);
b6958ce44   Eddie Dong   KVM: Emulate hlt ...
1418
  }
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1419
1420
  void kvm_resched(struct kvm_vcpu *vcpu)
  {
3fca03653   Yaozu Dong   KVM: VMX: Avoid u...
1421
1422
  	if (!need_resched())
  		return;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1423
  	cond_resched();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1424
1425
  }
  EXPORT_SYMBOL_GPL(kvm_resched);
217ece612   Rik van Riel   KVM: use yield_to...
1426
  void kvm_vcpu_on_spin(struct kvm_vcpu *me)
d255f4f2b   Zhai, Edwin   KVM: introduce kv...
1427
  {
217ece612   Rik van Riel   KVM: use yield_to...
1428
1429
1430
1431
1432
1433
  	struct kvm *kvm = me->kvm;
  	struct kvm_vcpu *vcpu;
  	int last_boosted_vcpu = me->kvm->last_boosted_vcpu;
  	int yielded = 0;
  	int pass;
  	int i;
d255f4f2b   Zhai, Edwin   KVM: introduce kv...
1434

217ece612   Rik van Riel   KVM: use yield_to...
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
  	/*
  	 * We boost the priority of a VCPU that is runnable but not
  	 * currently running, because it got preempted by something
  	 * else and called schedule in __vcpu_run.  Hopefully that
  	 * VCPU is holding the lock that we need and will release it.
  	 * We approximate round-robin by starting at the last boosted VCPU.
  	 */
  	for (pass = 0; pass < 2 && !yielded; pass++) {
  		kvm_for_each_vcpu(i, vcpu, kvm) {
  			struct task_struct *task = NULL;
  			struct pid *pid;
  			if (!pass && i < last_boosted_vcpu) {
  				i = last_boosted_vcpu;
  				continue;
  			} else if (pass && i > last_boosted_vcpu)
  				break;
  			if (vcpu == me)
  				continue;
  			if (waitqueue_active(&vcpu->wq))
  				continue;
  			rcu_read_lock();
  			pid = rcu_dereference(vcpu->pid);
  			if (pid)
  				task = get_pid_task(vcpu->pid, PIDTYPE_PID);
  			rcu_read_unlock();
  			if (!task)
  				continue;
  			if (task->flags & PF_VCPU) {
  				put_task_struct(task);
  				continue;
  			}
  			if (yield_to(task, 1)) {
  				put_task_struct(task);
  				kvm->last_boosted_vcpu = i;
  				yielded = 1;
  				break;
  			}
  			put_task_struct(task);
  		}
  	}
d255f4f2b   Zhai, Edwin   KVM: introduce kv...
1475
1476
  }
  EXPORT_SYMBOL_GPL(kvm_vcpu_on_spin);
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1477
  static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1478
1479
  {
  	struct kvm_vcpu *vcpu = vma->vm_file->private_data;
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1480
  	struct page *page;
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1481
  	if (vmf->pgoff == 0)
039576c03   Avi Kivity   KVM: Avoid guest ...
1482
  		page = virt_to_page(vcpu->run);
09566765e   Avi Kivity   KVM: Only x86 has...
1483
  #ifdef CONFIG_X86
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1484
  	else if (vmf->pgoff == KVM_PIO_PAGE_OFFSET)
ad312c7c7   Zhang Xiantao   KVM: Portability:...
1485
  		page = virt_to_page(vcpu->arch.pio_data);
09566765e   Avi Kivity   KVM: Only x86 has...
1486
  #endif
5f94c1741   Laurent Vivier   KVM: Add coalesce...
1487
1488
1489
1490
  #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
  	else if (vmf->pgoff == KVM_COALESCED_MMIO_PAGE_OFFSET)
  		page = virt_to_page(vcpu->kvm->coalesced_mmio_ring);
  #endif
039576c03   Avi Kivity   KVM: Avoid guest ...
1491
  	else
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1492
  		return VM_FAULT_SIGBUS;
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1493
  	get_page(page);
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1494
1495
  	vmf->page = page;
  	return 0;
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1496
  }
f0f37e2f7   Alexey Dobriyan   const: mark struc...
1497
  static const struct vm_operations_struct kvm_vcpu_vm_ops = {
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1498
  	.fault = kvm_vcpu_fault,
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1499
1500
1501
1502
1503
1504
1505
  };
  
  static int kvm_vcpu_mmap(struct file *file, struct vm_area_struct *vma)
  {
  	vma->vm_ops = &kvm_vcpu_vm_ops;
  	return 0;
  }
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1506
1507
1508
  static int kvm_vcpu_release(struct inode *inode, struct file *filp)
  {
  	struct kvm_vcpu *vcpu = filp->private_data;
66c0b394f   Al Viro   KVM: kill file->f...
1509
  	kvm_put_kvm(vcpu->kvm);
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1510
1511
  	return 0;
  }
3d3aab1b9   Christian Borntraeger   KVM: set owner of...
1512
  static struct file_operations kvm_vcpu_fops = {
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1513
1514
  	.release        = kvm_vcpu_release,
  	.unlocked_ioctl = kvm_vcpu_ioctl,
1dda606c5   Alexander Graf   KVM: Add compat i...
1515
1516
1517
  #ifdef CONFIG_COMPAT
  	.compat_ioctl   = kvm_vcpu_compat_ioctl,
  #endif
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1518
  	.mmap           = kvm_vcpu_mmap,
6038f373a   Arnd Bergmann   llseek: automatic...
1519
  	.llseek		= noop_llseek,
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1520
1521
1522
1523
1524
1525
1526
  };
  
  /*
   * Allocates an inode for the vcpu.
   */
  static int create_vcpu_fd(struct kvm_vcpu *vcpu)
  {
628ff7c1d   Roland Dreier   anonfd: Allow mak...
1527
  	return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, O_RDWR);
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1528
  }
c5ea76600   Avi Kivity   KVM: Move kvm_vm_...
1529
1530
1531
  /*
   * Creates some virtual cpus.  Good luck creating more than one.
   */
73880c80a   Gleb Natapov   KVM: Break depend...
1532
  static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
c5ea76600   Avi Kivity   KVM: Move kvm_vm_...
1533
1534
  {
  	int r;
988a2cae6   Gleb Natapov   KVM: Use macro to...
1535
  	struct kvm_vcpu *vcpu, *v;
c5ea76600   Avi Kivity   KVM: Move kvm_vm_...
1536

73880c80a   Gleb Natapov   KVM: Break depend...
1537
  	vcpu = kvm_arch_vcpu_create(kvm, id);
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
1538
1539
  	if (IS_ERR(vcpu))
  		return PTR_ERR(vcpu);
c5ea76600   Avi Kivity   KVM: Move kvm_vm_...
1540

15ad71460   Avi Kivity   KVM: Use the sche...
1541
  	preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops);
26e5215fd   Avi Kivity   KVM: Split vcpu c...
1542
1543
  	r = kvm_arch_vcpu_setup(vcpu);
  	if (r)
d780592b9   Jan Kiszka   KVM: Clean up err...
1544
  		goto vcpu_destroy;
26e5215fd   Avi Kivity   KVM: Split vcpu c...
1545

11ec28047   Shaohua Li   KVM: Convert vm l...
1546
  	mutex_lock(&kvm->lock);
73880c80a   Gleb Natapov   KVM: Break depend...
1547
1548
  	if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) {
  		r = -EINVAL;
d780592b9   Jan Kiszka   KVM: Clean up err...
1549
  		goto unlock_vcpu_destroy;
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
1550
  	}
73880c80a   Gleb Natapov   KVM: Break depend...
1551

988a2cae6   Gleb Natapov   KVM: Use macro to...
1552
1553
  	kvm_for_each_vcpu(r, v, kvm)
  		if (v->vcpu_id == id) {
73880c80a   Gleb Natapov   KVM: Break depend...
1554
  			r = -EEXIST;
d780592b9   Jan Kiszka   KVM: Clean up err...
1555
  			goto unlock_vcpu_destroy;
73880c80a   Gleb Natapov   KVM: Break depend...
1556
1557
1558
  		}
  
  	BUG_ON(kvm->vcpus[atomic_read(&kvm->online_vcpus)]);
c5ea76600   Avi Kivity   KVM: Move kvm_vm_...
1559

fb3f0f51d   Rusty Russell   KVM: Dynamically ...
1560
  	/* Now it's all set up, let userspace reach it */
66c0b394f   Al Viro   KVM: kill file->f...
1561
  	kvm_get_kvm(kvm);
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1562
  	r = create_vcpu_fd(vcpu);
73880c80a   Gleb Natapov   KVM: Break depend...
1563
1564
  	if (r < 0) {
  		kvm_put_kvm(kvm);
d780592b9   Jan Kiszka   KVM: Clean up err...
1565
  		goto unlock_vcpu_destroy;
73880c80a   Gleb Natapov   KVM: Break depend...
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
  	}
  
  	kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu;
  	smp_wmb();
  	atomic_inc(&kvm->online_vcpus);
  
  #ifdef CONFIG_KVM_APIC_ARCHITECTURE
  	if (kvm->bsp_vcpu_id == id)
  		kvm->bsp_vcpu = vcpu;
  #endif
  	mutex_unlock(&kvm->lock);
fb3f0f51d   Rusty Russell   KVM: Dynamically ...
1577
  	return r;
39c3b86e5   Avi Kivity   KVM: Keep an uppe...
1578

d780592b9   Jan Kiszka   KVM: Clean up err...
1579
  unlock_vcpu_destroy:
7d8fece67   Glauber Costa   KVM: Don't destro...
1580
  	mutex_unlock(&kvm->lock);
d780592b9   Jan Kiszka   KVM: Clean up err...
1581
  vcpu_destroy:
d40ccc624   Hollis Blanchard   KVM: Correct cons...
1582
  	kvm_arch_vcpu_destroy(vcpu);
c5ea76600   Avi Kivity   KVM: Move kvm_vm_...
1583
1584
  	return r;
  }
1961d276c   Avi Kivity   KVM: Add guest mo...
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
  static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset)
  {
  	if (sigset) {
  		sigdelsetmask(sigset, sigmask(SIGKILL)|sigmask(SIGSTOP));
  		vcpu->sigset_active = 1;
  		vcpu->sigset = *sigset;
  	} else
  		vcpu->sigset_active = 0;
  	return 0;
  }
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1595
1596
  static long kvm_vcpu_ioctl(struct file *filp,
  			   unsigned int ioctl, unsigned long arg)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1597
  {
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1598
  	struct kvm_vcpu *vcpu = filp->private_data;
2f3669879   Al Viro   [PATCH] kvm: __us...
1599
  	void __user *argp = (void __user *)arg;
313a3dc75   Carsten Otte   KVM: Portability:...
1600
  	int r;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1601
1602
  	struct kvm_fpu *fpu = NULL;
  	struct kvm_sregs *kvm_sregs = NULL;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1603

6d4e4c4fc   Avi Kivity   KVM: Disallow for...
1604
1605
  	if (vcpu->kvm->mm != current->mm)
  		return -EIO;
2122ff5ea   Avi Kivity   KVM: move vcpu lo...
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
  
  #if defined(CONFIG_S390) || defined(CONFIG_PPC)
  	/*
  	 * Special cases: vcpu ioctls that are asynchronous to vcpu execution,
  	 * so vcpu_load() would break it.
  	 */
  	if (ioctl == KVM_S390_INTERRUPT || ioctl == KVM_INTERRUPT)
  		return kvm_arch_vcpu_ioctl(filp, ioctl, arg);
  #endif
  
  
  	vcpu_load(vcpu);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1618
  	switch (ioctl) {
9a2bb7f48   Avi Kivity   KVM: Use a shared...
1619
  	case KVM_RUN:
f0fe51086   Avi Kivity   KVM: Future-proof...
1620
1621
1622
  		r = -EINVAL;
  		if (arg)
  			goto out;
b6c7a5dcc   Hollis Blanchard   KVM: Portability:...
1623
  		r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
64be50070   Gleb Natapov   KVM: x86: trace "...
1624
  		trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1625
  		break;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1626
  	case KVM_GET_REGS: {
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1627
  		struct kvm_regs *kvm_regs;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1628

3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1629
1630
1631
  		r = -ENOMEM;
  		kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL);
  		if (!kvm_regs)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1632
  			goto out;
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1633
1634
1635
  		r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs);
  		if (r)
  			goto out_free1;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1636
  		r = -EFAULT;
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1637
1638
  		if (copy_to_user(argp, kvm_regs, sizeof(struct kvm_regs)))
  			goto out_free1;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1639
  		r = 0;
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1640
1641
  out_free1:
  		kfree(kvm_regs);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1642
1643
1644
  		break;
  	}
  	case KVM_SET_REGS: {
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1645
  		struct kvm_regs *kvm_regs;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1646

3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1647
1648
1649
  		r = -ENOMEM;
  		kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL);
  		if (!kvm_regs)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1650
  			goto out;
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1651
1652
1653
1654
  		r = -EFAULT;
  		if (copy_from_user(kvm_regs, argp, sizeof(struct kvm_regs)))
  			goto out_free2;
  		r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1655
  		if (r)
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1656
  			goto out_free2;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1657
  		r = 0;
3e4bb3ac9   Xiantao Zhang   KVM: Use kzalloc ...
1658
1659
  out_free2:
  		kfree(kvm_regs);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1660
1661
1662
  		break;
  	}
  	case KVM_GET_SREGS: {
fa3795a73   Dave Hansen   KVM: Reduce stack...
1663
1664
1665
1666
1667
  		kvm_sregs = kzalloc(sizeof(struct kvm_sregs), GFP_KERNEL);
  		r = -ENOMEM;
  		if (!kvm_sregs)
  			goto out;
  		r = kvm_arch_vcpu_ioctl_get_sregs(vcpu, kvm_sregs);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1668
1669
1670
  		if (r)
  			goto out;
  		r = -EFAULT;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1671
  		if (copy_to_user(argp, kvm_sregs, sizeof(struct kvm_sregs)))
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1672
1673
1674
1675
1676
  			goto out;
  		r = 0;
  		break;
  	}
  	case KVM_SET_SREGS: {
fa3795a73   Dave Hansen   KVM: Reduce stack...
1677
1678
1679
1680
  		kvm_sregs = kmalloc(sizeof(struct kvm_sregs), GFP_KERNEL);
  		r = -ENOMEM;
  		if (!kvm_sregs)
  			goto out;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1681
  		r = -EFAULT;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1682
  		if (copy_from_user(kvm_sregs, argp, sizeof(struct kvm_sregs)))
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1683
  			goto out;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1684
  		r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, kvm_sregs);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1685
1686
1687
1688
1689
  		if (r)
  			goto out;
  		r = 0;
  		break;
  	}
62d9f0dbc   Marcelo Tosatti   KVM: add ioctls t...
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  	case KVM_GET_MP_STATE: {
  		struct kvm_mp_state mp_state;
  
  		r = kvm_arch_vcpu_ioctl_get_mpstate(vcpu, &mp_state);
  		if (r)
  			goto out;
  		r = -EFAULT;
  		if (copy_to_user(argp, &mp_state, sizeof mp_state))
  			goto out;
  		r = 0;
  		break;
  	}
  	case KVM_SET_MP_STATE: {
  		struct kvm_mp_state mp_state;
  
  		r = -EFAULT;
  		if (copy_from_user(&mp_state, argp, sizeof mp_state))
  			goto out;
  		r = kvm_arch_vcpu_ioctl_set_mpstate(vcpu, &mp_state);
  		if (r)
  			goto out;
  		r = 0;
  		break;
  	}
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1714
1715
1716
1717
  	case KVM_TRANSLATE: {
  		struct kvm_translation tr;
  
  		r = -EFAULT;
2f3669879   Al Viro   [PATCH] kvm: __us...
1718
  		if (copy_from_user(&tr, argp, sizeof tr))
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1719
  			goto out;
8b0067913   Zhang Xiantao   KVM: Portability:...
1720
  		r = kvm_arch_vcpu_ioctl_translate(vcpu, &tr);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1721
1722
1723
  		if (r)
  			goto out;
  		r = -EFAULT;
2f3669879   Al Viro   [PATCH] kvm: __us...
1724
  		if (copy_to_user(argp, &tr, sizeof tr))
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1725
1726
1727
1728
  			goto out;
  		r = 0;
  		break;
  	}
d0bfb940e   Jan Kiszka   KVM: New guest de...
1729
1730
  	case KVM_SET_GUEST_DEBUG: {
  		struct kvm_guest_debug dbg;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1731
1732
  
  		r = -EFAULT;
2f3669879   Al Viro   [PATCH] kvm: __us...
1733
  		if (copy_from_user(&dbg, argp, sizeof dbg))
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1734
  			goto out;
d0bfb940e   Jan Kiszka   KVM: New guest de...
1735
  		r = kvm_arch_vcpu_ioctl_set_guest_debug(vcpu, &dbg);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1736
1737
1738
1739
1740
  		if (r)
  			goto out;
  		r = 0;
  		break;
  	}
1961d276c   Avi Kivity   KVM: Add guest mo...
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
  	case KVM_SET_SIGNAL_MASK: {
  		struct kvm_signal_mask __user *sigmask_arg = argp;
  		struct kvm_signal_mask kvm_sigmask;
  		sigset_t sigset, *p;
  
  		p = NULL;
  		if (argp) {
  			r = -EFAULT;
  			if (copy_from_user(&kvm_sigmask, argp,
  					   sizeof kvm_sigmask))
  				goto out;
  			r = -EINVAL;
  			if (kvm_sigmask.len != sizeof sigset)
  				goto out;
  			r = -EFAULT;
  			if (copy_from_user(&sigset, sigmask_arg->sigset,
  					   sizeof sigset))
  				goto out;
  			p = &sigset;
  		}
376d41ff2   Andi Kleen   KVM: Fix KVM_SET_...
1761
  		r = kvm_vcpu_ioctl_set_sigmask(vcpu, p);
1961d276c   Avi Kivity   KVM: Add guest mo...
1762
1763
  		break;
  	}
b8836737d   Avi Kivity   KVM: Add fpu get/...
1764
  	case KVM_GET_FPU: {
fa3795a73   Dave Hansen   KVM: Reduce stack...
1765
1766
1767
1768
1769
  		fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL);
  		r = -ENOMEM;
  		if (!fpu)
  			goto out;
  		r = kvm_arch_vcpu_ioctl_get_fpu(vcpu, fpu);
b8836737d   Avi Kivity   KVM: Add fpu get/...
1770
1771
1772
  		if (r)
  			goto out;
  		r = -EFAULT;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1773
  		if (copy_to_user(argp, fpu, sizeof(struct kvm_fpu)))
b8836737d   Avi Kivity   KVM: Add fpu get/...
1774
1775
1776
1777
1778
  			goto out;
  		r = 0;
  		break;
  	}
  	case KVM_SET_FPU: {
fa3795a73   Dave Hansen   KVM: Reduce stack...
1779
1780
1781
1782
  		fpu = kmalloc(sizeof(struct kvm_fpu), GFP_KERNEL);
  		r = -ENOMEM;
  		if (!fpu)
  			goto out;
b8836737d   Avi Kivity   KVM: Add fpu get/...
1783
  		r = -EFAULT;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1784
  		if (copy_from_user(fpu, argp, sizeof(struct kvm_fpu)))
b8836737d   Avi Kivity   KVM: Add fpu get/...
1785
  			goto out;
fa3795a73   Dave Hansen   KVM: Reduce stack...
1786
  		r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, fpu);
b8836737d   Avi Kivity   KVM: Add fpu get/...
1787
1788
1789
1790
1791
  		if (r)
  			goto out;
  		r = 0;
  		break;
  	}
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1792
  	default:
313a3dc75   Carsten Otte   KVM: Portability:...
1793
  		r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1794
1795
  	}
  out:
2122ff5ea   Avi Kivity   KVM: move vcpu lo...
1796
  	vcpu_put(vcpu);
fa3795a73   Dave Hansen   KVM: Reduce stack...
1797
1798
  	kfree(fpu);
  	kfree(kvm_sregs);
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1799
1800
  	return r;
  }
1dda606c5   Alexander Graf   KVM: Add compat i...
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
  #ifdef CONFIG_COMPAT
  static long kvm_vcpu_compat_ioctl(struct file *filp,
  				  unsigned int ioctl, unsigned long arg)
  {
  	struct kvm_vcpu *vcpu = filp->private_data;
  	void __user *argp = compat_ptr(arg);
  	int r;
  
  	if (vcpu->kvm->mm != current->mm)
  		return -EIO;
  
  	switch (ioctl) {
  	case KVM_SET_SIGNAL_MASK: {
  		struct kvm_signal_mask __user *sigmask_arg = argp;
  		struct kvm_signal_mask kvm_sigmask;
  		compat_sigset_t csigset;
  		sigset_t sigset;
  
  		if (argp) {
  			r = -EFAULT;
  			if (copy_from_user(&kvm_sigmask, argp,
  					   sizeof kvm_sigmask))
  				goto out;
  			r = -EINVAL;
  			if (kvm_sigmask.len != sizeof csigset)
  				goto out;
  			r = -EFAULT;
  			if (copy_from_user(&csigset, sigmask_arg->sigset,
  					   sizeof csigset))
  				goto out;
  		}
  		sigset_from_compat(&sigset, &csigset);
  		r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
  		break;
  	}
  	default:
  		r = kvm_vcpu_ioctl(filp, ioctl, arg);
  	}
  
  out:
  	return r;
  }
  #endif
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1844
1845
1846
1847
1848
  static long kvm_vm_ioctl(struct file *filp,
  			   unsigned int ioctl, unsigned long arg)
  {
  	struct kvm *kvm = filp->private_data;
  	void __user *argp = (void __user *)arg;
1fe779f8e   Carsten Otte   KVM: Portability:...
1849
  	int r;
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1850

6d4e4c4fc   Avi Kivity   KVM: Disallow for...
1851
1852
  	if (kvm->mm != current->mm)
  		return -EIO;
bccf2150f   Avi Kivity   KVM: Per-vcpu inodes
1853
1854
1855
1856
1857
1858
  	switch (ioctl) {
  	case KVM_CREATE_VCPU:
  		r = kvm_vm_ioctl_create_vcpu(kvm, arg);
  		if (r < 0)
  			goto out;
  		break;
6fc138d22   Izik Eidus   KVM: Support assi...
1859
1860
1861
1862
1863
1864
1865
1866
1867
  	case KVM_SET_USER_MEMORY_REGION: {
  		struct kvm_userspace_memory_region kvm_userspace_mem;
  
  		r = -EFAULT;
  		if (copy_from_user(&kvm_userspace_mem, argp,
  						sizeof kvm_userspace_mem))
  			goto out;
  
  		r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem, 1);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1868
1869
1870
1871
1872
1873
1874
1875
  		if (r)
  			goto out;
  		break;
  	}
  	case KVM_GET_DIRTY_LOG: {
  		struct kvm_dirty_log log;
  
  		r = -EFAULT;
2f3669879   Al Viro   [PATCH] kvm: __us...
1876
  		if (copy_from_user(&log, argp, sizeof log))
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1877
  			goto out;
2c6f5df97   Avi Kivity   KVM: Rename some ...
1878
  		r = kvm_vm_ioctl_get_dirty_log(kvm, &log);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
1879
1880
1881
1882
  		if (r)
  			goto out;
  		break;
  	}
5f94c1741   Laurent Vivier   KVM: Add coalesce...
1883
1884
1885
1886
1887
1888
  #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
  	case KVM_REGISTER_COALESCED_MMIO: {
  		struct kvm_coalesced_mmio_zone zone;
  		r = -EFAULT;
  		if (copy_from_user(&zone, argp, sizeof zone))
  			goto out;
5f94c1741   Laurent Vivier   KVM: Add coalesce...
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
  		r = kvm_vm_ioctl_register_coalesced_mmio(kvm, &zone);
  		if (r)
  			goto out;
  		r = 0;
  		break;
  	}
  	case KVM_UNREGISTER_COALESCED_MMIO: {
  		struct kvm_coalesced_mmio_zone zone;
  		r = -EFAULT;
  		if (copy_from_user(&zone, argp, sizeof zone))
  			goto out;
5f94c1741   Laurent Vivier   KVM: Add coalesce...
1900
1901
1902
1903
1904
1905
1906
  		r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, &zone);
  		if (r)
  			goto out;
  		r = 0;
  		break;
  	}
  #endif
721eecbf4   Gregory Haskins   KVM: irqfd
1907
1908
1909
1910
1911
1912
1913
1914
1915
  	case KVM_IRQFD: {
  		struct kvm_irqfd data;
  
  		r = -EFAULT;
  		if (copy_from_user(&data, argp, sizeof data))
  			goto out;
  		r = kvm_irqfd(kvm, data.fd, data.gsi, data.flags);
  		break;
  	}
d34e6b175   Gregory Haskins   KVM: add ioeventf...
1916
1917
1918
1919
1920
1921
1922
1923
1924
  	case KVM_IOEVENTFD: {
  		struct kvm_ioeventfd data;
  
  		r = -EFAULT;
  		if (copy_from_user(&data, argp, sizeof data))
  			goto out;
  		r = kvm_ioeventfd(kvm, &data);
  		break;
  	}
73880c80a   Gleb Natapov   KVM: Break depend...
1925
1926
1927
  #ifdef CONFIG_KVM_APIC_ARCHITECTURE
  	case KVM_SET_BOOT_CPU_ID:
  		r = 0;
894a9c554   Marcelo Tosatti   KVM: x86: missing...
1928
  		mutex_lock(&kvm->lock);
73880c80a   Gleb Natapov   KVM: Break depend...
1929
1930
1931
1932
  		if (atomic_read(&kvm->online_vcpus) != 0)
  			r = -EBUSY;
  		else
  			kvm->bsp_vcpu_id = arg;
894a9c554   Marcelo Tosatti   KVM: x86: missing...
1933
  		mutex_unlock(&kvm->lock);
73880c80a   Gleb Natapov   KVM: Break depend...
1934
1935
  		break;
  #endif
f17abe9a4   Avi Kivity   KVM: Create an in...
1936
  	default:
1fe779f8e   Carsten Otte   KVM: Portability:...
1937
  		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
bfd99ff5d   Avi Kivity   KVM: Move assigne...
1938
1939
  		if (r == -ENOTTY)
  			r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg);
f17abe9a4   Avi Kivity   KVM: Create an in...
1940
1941
1942
1943
  	}
  out:
  	return r;
  }
6ff5894cd   Arnd Bergmann   KVM: Enable 32bit...
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
  #ifdef CONFIG_COMPAT
  struct compat_kvm_dirty_log {
  	__u32 slot;
  	__u32 padding1;
  	union {
  		compat_uptr_t dirty_bitmap; /* one bit per page */
  		__u64 padding2;
  	};
  };
  
  static long kvm_vm_compat_ioctl(struct file *filp,
  			   unsigned int ioctl, unsigned long arg)
  {
  	struct kvm *kvm = filp->private_data;
  	int r;
  
  	if (kvm->mm != current->mm)
  		return -EIO;
  	switch (ioctl) {
  	case KVM_GET_DIRTY_LOG: {
  		struct compat_kvm_dirty_log compat_log;
  		struct kvm_dirty_log log;
  
  		r = -EFAULT;
  		if (copy_from_user(&compat_log, (void __user *)arg,
  				   sizeof(compat_log)))
  			goto out;
  		log.slot	 = compat_log.slot;
  		log.padding1	 = compat_log.padding1;
  		log.padding2	 = compat_log.padding2;
  		log.dirty_bitmap = compat_ptr(compat_log.dirty_bitmap);
  
  		r = kvm_vm_ioctl_get_dirty_log(kvm, &log);
  		if (r)
  			goto out;
  		break;
  	}
  	default:
  		r = kvm_vm_ioctl(filp, ioctl, arg);
  	}
  
  out:
  	return r;
  }
  #endif
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1989
  static int kvm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
f17abe9a4   Avi Kivity   KVM: Create an in...
1990
  {
777b3f49d   Marcelo Tosatti   KVM: opencode gfn...
1991
1992
1993
1994
  	struct page *page[1];
  	unsigned long addr;
  	int npages;
  	gfn_t gfn = vmf->pgoff;
f17abe9a4   Avi Kivity   KVM: Create an in...
1995
  	struct kvm *kvm = vma->vm_file->private_data;
f17abe9a4   Avi Kivity   KVM: Create an in...
1996

777b3f49d   Marcelo Tosatti   KVM: opencode gfn...
1997
1998
  	addr = gfn_to_hva(kvm, gfn);
  	if (kvm_is_error_hva(addr))
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
1999
  		return VM_FAULT_SIGBUS;
777b3f49d   Marcelo Tosatti   KVM: opencode gfn...
2000
2001
2002
2003
  
  	npages = get_user_pages(current, current->mm, addr, 1, 1, 0, page,
  				NULL);
  	if (unlikely(npages != 1))
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
2004
  		return VM_FAULT_SIGBUS;
777b3f49d   Marcelo Tosatti   KVM: opencode gfn...
2005
2006
  
  	vmf->page = page[0];
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
2007
  	return 0;
f17abe9a4   Avi Kivity   KVM: Create an in...
2008
  }
f0f37e2f7   Alexey Dobriyan   const: mark struc...
2009
  static const struct vm_operations_struct kvm_vm_vm_ops = {
e4a533a41   npiggin@suse.de   KVM: Convert KVM ...
2010
  	.fault = kvm_vm_fault,
f17abe9a4   Avi Kivity   KVM: Create an in...
2011
2012
2013
2014
2015
2016
2017
  };
  
  static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma)
  {
  	vma->vm_ops = &kvm_vm_vm_ops;
  	return 0;
  }
3d3aab1b9   Christian Borntraeger   KVM: set owner of...
2018
  static struct file_operations kvm_vm_fops = {
f17abe9a4   Avi Kivity   KVM: Create an in...
2019
2020
  	.release        = kvm_vm_release,
  	.unlocked_ioctl = kvm_vm_ioctl,
6ff5894cd   Arnd Bergmann   KVM: Enable 32bit...
2021
2022
2023
  #ifdef CONFIG_COMPAT
  	.compat_ioctl   = kvm_vm_compat_ioctl,
  #endif
f17abe9a4   Avi Kivity   KVM: Create an in...
2024
  	.mmap           = kvm_vm_mmap,
6038f373a   Arnd Bergmann   llseek: automatic...
2025
  	.llseek		= noop_llseek,
f17abe9a4   Avi Kivity   KVM: Create an in...
2026
2027
2028
2029
  };
  
  static int kvm_dev_ioctl_create_vm(void)
  {
aac876369   Heiko Carstens   KVM: get rid of w...
2030
  	int r;
f17abe9a4   Avi Kivity   KVM: Create an in...
2031
  	struct kvm *kvm;
f17abe9a4   Avi Kivity   KVM: Create an in...
2032
  	kvm = kvm_create_vm();
d6d281684   Avi Kivity   KVM: Remove kvmfs...
2033
2034
  	if (IS_ERR(kvm))
  		return PTR_ERR(kvm);
6ce5a090a   Takuya Yoshikawa   KVM: coalesced_mm...
2035
2036
2037
2038
2039
2040
2041
  #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
  	r = kvm_coalesced_mmio_init(kvm);
  	if (r < 0) {
  		kvm_put_kvm(kvm);
  		return r;
  	}
  #endif
aac876369   Heiko Carstens   KVM: get rid of w...
2042
2043
  	r = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
  	if (r < 0)
66c0b394f   Al Viro   KVM: kill file->f...
2044
  		kvm_put_kvm(kvm);
f17abe9a4   Avi Kivity   KVM: Create an in...
2045

aac876369   Heiko Carstens   KVM: get rid of w...
2046
  	return r;
f17abe9a4   Avi Kivity   KVM: Create an in...
2047
  }
1a811b616   Avi Kivity   KVM: Advertise th...
2048
2049
2050
  static long kvm_dev_ioctl_check_extension_generic(long arg)
  {
  	switch (arg) {
ca9edaee1   Avi Kivity   KVM: Consolidate ...
2051
  	case KVM_CAP_USER_MEMORY:
1a811b616   Avi Kivity   KVM: Advertise th...
2052
  	case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
4cd481f68   Jan Kiszka   KVM: Fix overlapp...
2053
  	case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS:
73880c80a   Gleb Natapov   KVM: Break depend...
2054
2055
2056
  #ifdef CONFIG_KVM_APIC_ARCHITECTURE
  	case KVM_CAP_SET_BOOT_CPU_ID:
  #endif
a9c7399d6   Avi Kivity   KVM: Allow intern...
2057
  	case KVM_CAP_INTERNAL_ERROR_DATA:
1a811b616   Avi Kivity   KVM: Advertise th...
2058
  		return 1;
399ec807d   Avi Kivity   KVM: Userspace co...
2059
2060
  #ifdef CONFIG_HAVE_KVM_IRQCHIP
  	case KVM_CAP_IRQ_ROUTING:
36463146f   Sheng Yang   KVM: Get support ...
2061
  		return KVM_MAX_IRQ_ROUTES;
399ec807d   Avi Kivity   KVM: Userspace co...
2062
  #endif
1a811b616   Avi Kivity   KVM: Advertise th...
2063
2064
2065
2066
2067
  	default:
  		break;
  	}
  	return kvm_dev_ioctl_check_extension(arg);
  }
f17abe9a4   Avi Kivity   KVM: Create an in...
2068
2069
2070
  static long kvm_dev_ioctl(struct file *filp,
  			  unsigned int ioctl, unsigned long arg)
  {
07c45a366   Avi Kivity   KVM: Allow kernel...
2071
  	long r = -EINVAL;
f17abe9a4   Avi Kivity   KVM: Create an in...
2072
2073
2074
  
  	switch (ioctl) {
  	case KVM_GET_API_VERSION:
f0fe51086   Avi Kivity   KVM: Future-proof...
2075
2076
2077
  		r = -EINVAL;
  		if (arg)
  			goto out;
f17abe9a4   Avi Kivity   KVM: Create an in...
2078
2079
2080
  		r = KVM_API_VERSION;
  		break;
  	case KVM_CREATE_VM:
f0fe51086   Avi Kivity   KVM: Future-proof...
2081
2082
2083
  		r = -EINVAL;
  		if (arg)
  			goto out;
f17abe9a4   Avi Kivity   KVM: Create an in...
2084
2085
  		r = kvm_dev_ioctl_create_vm();
  		break;
018d00d2f   Zhang Xiantao   KVM: Portability:...
2086
  	case KVM_CHECK_EXTENSION:
1a811b616   Avi Kivity   KVM: Advertise th...
2087
  		r = kvm_dev_ioctl_check_extension_generic(arg);
5d308f455   Avi Kivity   KVM: Add method t...
2088
  		break;
07c45a366   Avi Kivity   KVM: Allow kernel...
2089
2090
2091
2092
  	case KVM_GET_VCPU_MMAP_SIZE:
  		r = -EINVAL;
  		if (arg)
  			goto out;
adb1ff467   Avi Kivity   KVM: Limit vcpu m...
2093
2094
2095
2096
  		r = PAGE_SIZE;     /* struct kvm_run */
  #ifdef CONFIG_X86
  		r += PAGE_SIZE;    /* pio data page */
  #endif
5f94c1741   Laurent Vivier   KVM: Add coalesce...
2097
2098
2099
  #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
  		r += PAGE_SIZE;    /* coalesced mmio ring page */
  #endif
07c45a366   Avi Kivity   KVM: Allow kernel...
2100
  		break;
d4c9ff2d1   Feng(Eric) Liu   KVM: Add kvm trac...
2101
2102
2103
  	case KVM_TRACE_ENABLE:
  	case KVM_TRACE_PAUSE:
  	case KVM_TRACE_DISABLE:
2023a29cb   Marcelo Tosatti   KVM: remove old K...
2104
  		r = -EOPNOTSUPP;
d4c9ff2d1   Feng(Eric) Liu   KVM: Add kvm trac...
2105
  		break;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2106
  	default:
043405e10   Carsten Otte   KVM: Move x86 msr...
2107
  		return kvm_arch_dev_ioctl(filp, ioctl, arg);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2108
2109
2110
2111
  	}
  out:
  	return r;
  }
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2112
  static struct file_operations kvm_chardev_ops = {
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2113
2114
  	.unlocked_ioctl = kvm_dev_ioctl,
  	.compat_ioctl   = kvm_dev_ioctl,
6038f373a   Arnd Bergmann   llseek: automatic...
2115
  	.llseek		= noop_llseek,
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2116
2117
2118
  };
  
  static struct miscdevice kvm_dev = {
bbe4432e6   Avi Kivity   KVM: Use own mino...
2119
  	KVM_MINOR,
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2120
2121
2122
  	"kvm",
  	&kvm_chardev_ops,
  };
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2123
  static void hardware_enable_nolock(void *junk)
1b6c01681   Avi Kivity   KVM: Keep track o...
2124
2125
  {
  	int cpu = raw_smp_processor_id();
10474ae89   Alexander Graf   KVM: Activate Vir...
2126
  	int r;
1b6c01681   Avi Kivity   KVM: Keep track o...
2127

7f59f492d   Rusty Russell   KVM: use cpumask_...
2128
  	if (cpumask_test_cpu(cpu, cpus_hardware_enabled))
1b6c01681   Avi Kivity   KVM: Keep track o...
2129
  		return;
10474ae89   Alexander Graf   KVM: Activate Vir...
2130

7f59f492d   Rusty Russell   KVM: use cpumask_...
2131
  	cpumask_set_cpu(cpu, cpus_hardware_enabled);
10474ae89   Alexander Graf   KVM: Activate Vir...
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
  
  	r = kvm_arch_hardware_enable(NULL);
  
  	if (r) {
  		cpumask_clear_cpu(cpu, cpus_hardware_enabled);
  		atomic_inc(&hardware_enable_failed);
  		printk(KERN_INFO "kvm: enabling virtualization on "
  				 "CPU%d failed
  ", cpu);
  	}
1b6c01681   Avi Kivity   KVM: Keep track o...
2142
  }
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2143
2144
  static void hardware_enable(void *junk)
  {
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2145
  	raw_spin_lock(&kvm_lock);
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2146
  	hardware_enable_nolock(junk);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2147
  	raw_spin_unlock(&kvm_lock);
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2148
2149
2150
  }
  
  static void hardware_disable_nolock(void *junk)
1b6c01681   Avi Kivity   KVM: Keep track o...
2151
2152
  {
  	int cpu = raw_smp_processor_id();
7f59f492d   Rusty Russell   KVM: use cpumask_...
2153
  	if (!cpumask_test_cpu(cpu, cpus_hardware_enabled))
1b6c01681   Avi Kivity   KVM: Keep track o...
2154
  		return;
7f59f492d   Rusty Russell   KVM: use cpumask_...
2155
  	cpumask_clear_cpu(cpu, cpus_hardware_enabled);
e9b11c175   Zhang Xiantao   KVM: Portability:...
2156
  	kvm_arch_hardware_disable(NULL);
1b6c01681   Avi Kivity   KVM: Keep track o...
2157
  }
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2158
2159
  static void hardware_disable(void *junk)
  {
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2160
  	raw_spin_lock(&kvm_lock);
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2161
  	hardware_disable_nolock(junk);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2162
  	raw_spin_unlock(&kvm_lock);
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2163
  }
10474ae89   Alexander Graf   KVM: Activate Vir...
2164
2165
2166
2167
2168
2169
  static void hardware_disable_all_nolock(void)
  {
  	BUG_ON(!kvm_usage_count);
  
  	kvm_usage_count--;
  	if (!kvm_usage_count)
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2170
  		on_each_cpu(hardware_disable_nolock, NULL, 1);
10474ae89   Alexander Graf   KVM: Activate Vir...
2171
2172
2173
2174
  }
  
  static void hardware_disable_all(void)
  {
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2175
  	raw_spin_lock(&kvm_lock);
10474ae89   Alexander Graf   KVM: Activate Vir...
2176
  	hardware_disable_all_nolock();
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2177
  	raw_spin_unlock(&kvm_lock);
10474ae89   Alexander Graf   KVM: Activate Vir...
2178
2179
2180
2181
2182
  }
  
  static int hardware_enable_all(void)
  {
  	int r = 0;
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2183
  	raw_spin_lock(&kvm_lock);
10474ae89   Alexander Graf   KVM: Activate Vir...
2184
2185
2186
2187
  
  	kvm_usage_count++;
  	if (kvm_usage_count == 1) {
  		atomic_set(&hardware_enable_failed, 0);
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2188
  		on_each_cpu(hardware_enable_nolock, NULL, 1);
10474ae89   Alexander Graf   KVM: Activate Vir...
2189
2190
2191
2192
2193
2194
  
  		if (atomic_read(&hardware_enable_failed)) {
  			hardware_disable_all_nolock();
  			r = -EBUSY;
  		}
  	}
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2195
  	raw_spin_unlock(&kvm_lock);
10474ae89   Alexander Graf   KVM: Activate Vir...
2196
2197
2198
  
  	return r;
  }
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2199
2200
2201
2202
  static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
  			   void *v)
  {
  	int cpu = (long)v;
10474ae89   Alexander Graf   KVM: Activate Vir...
2203
2204
  	if (!kvm_usage_count)
  		return NOTIFY_OK;
1a6f4d7fb   Avi Kivity   KVM: Simplify CPU...
2205
  	val &= ~CPU_TASKS_FROZEN;
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2206
  	switch (val) {
cec9ad279   Avi Kivity   KVM: Use CPU_DYIN...
2207
  	case CPU_DYING:
6ec8a856e   Avi Kivity   KVM: Avoid callin...
2208
2209
2210
2211
2212
  		printk(KERN_INFO "kvm: disabling virtualization on CPU%d
  ",
  		       cpu);
  		hardware_disable(NULL);
  		break;
da908f2fb   Zachary Amsden   KVM: x86: Perform...
2213
  	case CPU_STARTING:
43934a38d   Jeremy Katz   KVM: Move virtual...
2214
2215
2216
  		printk(KERN_INFO "kvm: enabling virtualization on CPU%d
  ",
  		       cpu);
da908f2fb   Zachary Amsden   KVM: x86: Perform...
2217
  		hardware_enable(NULL);
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2218
2219
2220
2221
  		break;
  	}
  	return NOTIFY_OK;
  }
4ecac3fd6   Avi Kivity   KVM: Handle virtu...
2222

b7c4145ba   Avi Kivity   KVM: Don't spin o...
2223
  asmlinkage void kvm_spurious_fault(void)
4ecac3fd6   Avi Kivity   KVM: Handle virtu...
2224
  {
4ecac3fd6   Avi Kivity   KVM: Handle virtu...
2225
2226
2227
  	/* Fault while not rebooting.  We want the trace. */
  	BUG();
  }
b7c4145ba   Avi Kivity   KVM: Don't spin o...
2228
  EXPORT_SYMBOL_GPL(kvm_spurious_fault);
4ecac3fd6   Avi Kivity   KVM: Handle virtu...
2229

9a2b85c62   Rusty Russell   KVM: Trivial: Avo...
2230
  static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
d77c26fce   Mike Day   KVM: CodingStyle ...
2231
  		      void *v)
9a2b85c62   Rusty Russell   KVM: Trivial: Avo...
2232
  {
8e1c18157   Sheng Yang   KVM: VMX: Disable...
2233
2234
2235
2236
2237
2238
2239
2240
2241
  	/*
  	 * Some (well, at least mine) BIOSes hang on reboot if
  	 * in vmx root mode.
  	 *
  	 * And Intel TXT required VMX off for all cpu when system shutdown.
  	 */
  	printk(KERN_INFO "kvm: exiting hardware virtualization
  ");
  	kvm_rebooting = true;
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2242
  	on_each_cpu(hardware_disable_nolock, NULL, 1);
9a2b85c62   Rusty Russell   KVM: Trivial: Avo...
2243
2244
2245
2246
2247
2248
2249
  	return NOTIFY_OK;
  }
  
  static struct notifier_block kvm_reboot_notifier = {
  	.notifier_call = kvm_reboot,
  	.priority = 0,
  };
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2250
  static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2251
2252
2253
2254
2255
2256
2257
2258
  {
  	int i;
  
  	for (i = 0; i < bus->dev_count; i++) {
  		struct kvm_io_device *pos = bus->devs[i];
  
  		kvm_iodevice_destructor(pos);
  	}
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2259
  	kfree(bus);
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2260
  }
bda9020e2   Michael S. Tsirkin   KVM: remove in_ra...
2261
  /* kvm_io_bus_write - called under kvm->slots_lock */
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2262
  int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
bda9020e2   Michael S. Tsirkin   KVM: remove in_ra...
2263
  		     int len, const void *val)
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2264
2265
  {
  	int i;
90d83dc3d   Lai Jiangshan   KVM: use the corr...
2266
2267
2268
  	struct kvm_io_bus *bus;
  
  	bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
bda9020e2   Michael S. Tsirkin   KVM: remove in_ra...
2269
2270
2271
2272
2273
  	for (i = 0; i < bus->dev_count; i++)
  		if (!kvm_iodevice_write(bus->devs[i], addr, len, val))
  			return 0;
  	return -EOPNOTSUPP;
  }
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2274

bda9020e2   Michael S. Tsirkin   KVM: remove in_ra...
2275
  /* kvm_io_bus_read - called under kvm->slots_lock */
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2276
2277
  int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
  		    int len, void *val)
bda9020e2   Michael S. Tsirkin   KVM: remove in_ra...
2278
2279
  {
  	int i;
90d83dc3d   Lai Jiangshan   KVM: use the corr...
2280
  	struct kvm_io_bus *bus;
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2281

90d83dc3d   Lai Jiangshan   KVM: use the corr...
2282
  	bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
bda9020e2   Michael S. Tsirkin   KVM: remove in_ra...
2283
2284
2285
2286
  	for (i = 0; i < bus->dev_count; i++)
  		if (!kvm_iodevice_read(bus->devs[i], addr, len, val))
  			return 0;
  	return -EOPNOTSUPP;
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2287
  }
79fac95ec   Marcelo Tosatti   KVM: convert slot...
2288
  /* Caller must hold slots_lock. */
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2289
2290
  int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx,
  			    struct kvm_io_device *dev)
6c4746945   Michael S. Tsirkin   KVM: convert bus ...
2291
  {
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2292
  	struct kvm_io_bus *new_bus, *bus;
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2293

e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2294
  	bus = kvm->buses[bus_idx];
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2295
2296
  	if (bus->dev_count > NR_IOBUS_DEVS-1)
  		return -ENOSPC;
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2297

e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2298
2299
2300
2301
2302
2303
2304
2305
  	new_bus = kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL);
  	if (!new_bus)
  		return -ENOMEM;
  	memcpy(new_bus, bus, sizeof(struct kvm_io_bus));
  	new_bus->devs[new_bus->dev_count++] = dev;
  	rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
  	synchronize_srcu_expedited(&kvm->srcu);
  	kfree(bus);
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2306
2307
2308
  
  	return 0;
  }
79fac95ec   Marcelo Tosatti   KVM: convert slot...
2309
  /* Caller must hold slots_lock. */
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2310
2311
  int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
  			      struct kvm_io_device *dev)
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2312
  {
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2313
2314
  	int i, r;
  	struct kvm_io_bus *new_bus, *bus;
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2315

e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2316
2317
2318
  	new_bus = kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL);
  	if (!new_bus)
  		return -ENOMEM;
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2319

e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2320
2321
2322
2323
2324
2325
2326
2327
  	bus = kvm->buses[bus_idx];
  	memcpy(new_bus, bus, sizeof(struct kvm_io_bus));
  
  	r = -ENOENT;
  	for (i = 0; i < new_bus->dev_count; i++)
  		if (new_bus->devs[i] == dev) {
  			r = 0;
  			new_bus->devs[i] = new_bus->devs[--new_bus->dev_count];
090b7aff2   Gregory Haskins   KVM: make io_bus ...
2328
2329
  			break;
  		}
e93f8a0f8   Marcelo Tosatti   KVM: convert io_b...
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
  
  	if (r) {
  		kfree(new_bus);
  		return r;
  	}
  
  	rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
  	synchronize_srcu_expedited(&kvm->srcu);
  	kfree(bus);
  	return r;
2eeb2e94e   Gregory Haskins   KVM: Adds support...
2340
  }
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2341
2342
  static struct notifier_block kvm_cpu_notifier = {
  	.notifier_call = kvm_cpu_hotplug,
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2343
  };
8b88b0998   Christoph Hellwig   libfs: allow erro...
2344
  static int vm_stat_get(void *_offset, u64 *val)
ba1389b7a   Avi Kivity   KVM: Extend stats...
2345
2346
  {
  	unsigned offset = (long)_offset;
ba1389b7a   Avi Kivity   KVM: Extend stats...
2347
  	struct kvm *kvm;
8b88b0998   Christoph Hellwig   libfs: allow erro...
2348
  	*val = 0;
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2349
  	raw_spin_lock(&kvm_lock);
ba1389b7a   Avi Kivity   KVM: Extend stats...
2350
  	list_for_each_entry(kvm, &vm_list, vm_list)
8b88b0998   Christoph Hellwig   libfs: allow erro...
2351
  		*val += *(u32 *)((void *)kvm + offset);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2352
  	raw_spin_unlock(&kvm_lock);
8b88b0998   Christoph Hellwig   libfs: allow erro...
2353
  	return 0;
ba1389b7a   Avi Kivity   KVM: Extend stats...
2354
2355
2356
2357
  }
  
  DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu
  ");
8b88b0998   Christoph Hellwig   libfs: allow erro...
2358
  static int vcpu_stat_get(void *_offset, u64 *val)
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
2359
2360
  {
  	unsigned offset = (long)_offset;
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
2361
2362
2363
  	struct kvm *kvm;
  	struct kvm_vcpu *vcpu;
  	int i;
8b88b0998   Christoph Hellwig   libfs: allow erro...
2364
  	*val = 0;
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2365
  	raw_spin_lock(&kvm_lock);
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
2366
  	list_for_each_entry(kvm, &vm_list, vm_list)
988a2cae6   Gleb Natapov   KVM: Use macro to...
2367
2368
  		kvm_for_each_vcpu(i, vcpu, kvm)
  			*val += *(u32 *)((void *)vcpu + offset);
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2369
  	raw_spin_unlock(&kvm_lock);
8b88b0998   Christoph Hellwig   libfs: allow erro...
2370
  	return 0;
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
2371
  }
ba1389b7a   Avi Kivity   KVM: Extend stats...
2372
2373
  DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu
  ");
828c09509   Alexey Dobriyan   const: constify r...
2374
  static const struct file_operations *stat_fops[] = {
ba1389b7a   Avi Kivity   KVM: Extend stats...
2375
2376
2377
  	[KVM_STAT_VCPU] = &vcpu_stat_fops,
  	[KVM_STAT_VM]   = &vm_stat_fops,
  };
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
2378

a16b043cc   Zhang Xiantao   KVM: Remove __ini...
2379
  static void kvm_init_debug(void)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2380
2381
  {
  	struct kvm_stats_debugfs_item *p;
76f7c8790   Hollis Blanchard   KVM: Rename debug...
2382
  	kvm_debugfs_dir = debugfs_create_dir("kvm", NULL);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2383
  	for (p = debugfs_entries; p->name; ++p)
76f7c8790   Hollis Blanchard   KVM: Rename debug...
2384
  		p->dentry = debugfs_create_file(p->name, 0444, kvm_debugfs_dir,
1165f5fec   Avi Kivity   KVM: Per-vcpu sta...
2385
  						(void *)(long)p->offset,
ba1389b7a   Avi Kivity   KVM: Extend stats...
2386
  						stat_fops[p->kind]);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2387
2388
2389
2390
2391
2392
2393
2394
  }
  
  static void kvm_exit_debug(void)
  {
  	struct kvm_stats_debugfs_item *p;
  
  	for (p = debugfs_entries; p->name; ++p)
  		debugfs_remove(p->dentry);
76f7c8790   Hollis Blanchard   KVM: Rename debug...
2395
  	debugfs_remove(kvm_debugfs_dir);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2396
  }
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
2397
  static int kvm_suspend(void)
59ae6c6b8   Avi Kivity   [PATCH] KVM: Host...
2398
  {
10474ae89   Alexander Graf   KVM: Activate Vir...
2399
  	if (kvm_usage_count)
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2400
  		hardware_disable_nolock(NULL);
59ae6c6b8   Avi Kivity   [PATCH] KVM: Host...
2401
2402
  	return 0;
  }
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
2403
  static void kvm_resume(void)
59ae6c6b8   Avi Kivity   [PATCH] KVM: Host...
2404
  {
ca84d1a24   Zachary Amsden   KVM: x86: Add clo...
2405
  	if (kvm_usage_count) {
e935b8372   Jan Kiszka   KVM: Convert kvm_...
2406
  		WARN_ON(raw_spin_is_locked(&kvm_lock));
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2407
  		hardware_enable_nolock(NULL);
ca84d1a24   Zachary Amsden   KVM: x86: Add clo...
2408
  	}
59ae6c6b8   Avi Kivity   [PATCH] KVM: Host...
2409
  }
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
2410
  static struct syscore_ops kvm_syscore_ops = {
59ae6c6b8   Avi Kivity   [PATCH] KVM: Host...
2411
2412
2413
  	.suspend = kvm_suspend,
  	.resume = kvm_resume,
  };
cea7bb212   Izik Eidus   KVM: MMU: Make gf...
2414
  struct page *bad_page;
35149e212   Anthony Liguori   KVM: MMU: Don't a...
2415
  pfn_t bad_pfn;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2416

15ad71460   Avi Kivity   KVM: Use the sche...
2417
2418
2419
2420
2421
2422
2423
2424
2425
  static inline
  struct kvm_vcpu *preempt_notifier_to_vcpu(struct preempt_notifier *pn)
  {
  	return container_of(pn, struct kvm_vcpu, preempt_notifier);
  }
  
  static void kvm_sched_in(struct preempt_notifier *pn, int cpu)
  {
  	struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
e9b11c175   Zhang Xiantao   KVM: Portability:...
2426
  	kvm_arch_vcpu_load(vcpu, cpu);
15ad71460   Avi Kivity   KVM: Use the sche...
2427
2428
2429
2430
2431
2432
  }
  
  static void kvm_sched_out(struct preempt_notifier *pn,
  			  struct task_struct *next)
  {
  	struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
e9b11c175   Zhang Xiantao   KVM: Portability:...
2433
  	kvm_arch_vcpu_put(vcpu);
15ad71460   Avi Kivity   KVM: Use the sche...
2434
  }
0ee75bead   Avi Kivity   KVM: Let vcpu str...
2435
  int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
c16f862d0   Rusty Russell   KVM: Use kmem cac...
2436
  		  struct module *module)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2437
2438
  {
  	int r;
002c7f7c3   Yang, Sheng   KVM: VMX: Add cpu...
2439
  	int cpu;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2440

f8c16bbaa   Zhang Xiantao   KVM: Portability:...
2441
2442
  	r = kvm_arch_init(opaque);
  	if (r)
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2443
  		goto out_fail;
cb498ea2c   Zhang Xiantao   KVM: Portability:...
2444
2445
2446
2447
2448
2449
2450
  
  	bad_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
  
  	if (bad_page == NULL) {
  		r = -ENOMEM;
  		goto out;
  	}
35149e212   Anthony Liguori   KVM: MMU: Don't a...
2451
  	bad_pfn = page_to_pfn(bad_page);
bf998156d   Huang Ying   KVM: Avoid killin...
2452
2453
2454
2455
2456
2457
2458
2459
  	hwpoison_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
  
  	if (hwpoison_page == NULL) {
  		r = -ENOMEM;
  		goto out_free_0;
  	}
  
  	hwpoison_pfn = page_to_pfn(hwpoison_page);
edba23e51   Gleb Natapov   KVM: Return EFAUL...
2460
2461
2462
2463
2464
2465
2466
2467
  	fault_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
  
  	if (fault_page == NULL) {
  		r = -ENOMEM;
  		goto out_free_0;
  	}
  
  	fault_pfn = page_to_pfn(fault_page);
8437a6177   Avi Kivity   kvm: fix kvm rebo...
2468
  	if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) {
7f59f492d   Rusty Russell   KVM: use cpumask_...
2469
2470
2471
  		r = -ENOMEM;
  		goto out_free_0;
  	}
e9b11c175   Zhang Xiantao   KVM: Portability:...
2472
  	r = kvm_arch_hardware_setup();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2473
  	if (r < 0)
7f59f492d   Rusty Russell   KVM: use cpumask_...
2474
  		goto out_free_0a;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2475

002c7f7c3   Yang, Sheng   KVM: VMX: Add cpu...
2476
2477
  	for_each_online_cpu(cpu) {
  		smp_call_function_single(cpu,
e9b11c175   Zhang Xiantao   KVM: Portability:...
2478
  				kvm_arch_check_processor_compat,
8691e5a8f   Jens Axboe   smp_call_function...
2479
  				&r, 1);
002c7f7c3   Yang, Sheng   KVM: VMX: Add cpu...
2480
  		if (r < 0)
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2481
  			goto out_free_1;
002c7f7c3   Yang, Sheng   KVM: VMX: Add cpu...
2482
  	}
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2483
2484
  	r = register_cpu_notifier(&kvm_cpu_notifier);
  	if (r)
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2485
  		goto out_free_2;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2486
  	register_reboot_notifier(&kvm_reboot_notifier);
c16f862d0   Rusty Russell   KVM: Use kmem cac...
2487
  	/* A kmem cache lets us meet the alignment requirements of fx_save. */
0ee75bead   Avi Kivity   KVM: Let vcpu str...
2488
2489
2490
  	if (!vcpu_align)
  		vcpu_align = __alignof__(struct kvm_vcpu);
  	kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, vcpu_align,
56919c5c9   Joe Perches   KVM: Remove ptr c...
2491
  					   0, NULL);
c16f862d0   Rusty Russell   KVM: Use kmem cac...
2492
2493
  	if (!kvm_vcpu_cache) {
  		r = -ENOMEM;
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
2494
  		goto out_free_3;
c16f862d0   Rusty Russell   KVM: Use kmem cac...
2495
  	}
af585b921   Gleb Natapov   KVM: Halt vcpu if...
2496
2497
2498
  	r = kvm_async_pf_init();
  	if (r)
  		goto out_free;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2499
  	kvm_chardev_ops.owner = module;
3d3aab1b9   Christian Borntraeger   KVM: set owner of...
2500
2501
  	kvm_vm_fops.owner = module;
  	kvm_vcpu_fops.owner = module;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2502
2503
2504
  
  	r = misc_register(&kvm_dev);
  	if (r) {
d77c26fce   Mike Day   KVM: CodingStyle ...
2505
2506
  		printk(KERN_ERR "kvm: misc device register failed
  ");
af585b921   Gleb Natapov   KVM: Halt vcpu if...
2507
  		goto out_unreg;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2508
  	}
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
2509
  	register_syscore_ops(&kvm_syscore_ops);
15ad71460   Avi Kivity   KVM: Use the sche...
2510
2511
  	kvm_preempt_ops.sched_in = kvm_sched_in;
  	kvm_preempt_ops.sched_out = kvm_sched_out;
0ea4ed8e9   Darrick J. Wong   KVM: Prevent kvm_...
2512
  	kvm_init_debug();
c7addb902   Avi Kivity   KVM: Allow not-pr...
2513
  	return 0;
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2514

af585b921   Gleb Natapov   KVM: Halt vcpu if...
2515
2516
  out_unreg:
  	kvm_async_pf_deinit();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2517
  out_free:
c16f862d0   Rusty Russell   KVM: Use kmem cac...
2518
  	kmem_cache_destroy(kvm_vcpu_cache);
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2519
  out_free_3:
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2520
  	unregister_reboot_notifier(&kvm_reboot_notifier);
774c47f1d   Avi Kivity   [PATCH] KVM: cpu ...
2521
  	unregister_cpu_notifier(&kvm_cpu_notifier);
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2522
  out_free_2:
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2523
  out_free_1:
e9b11c175   Zhang Xiantao   KVM: Portability:...
2524
  	kvm_arch_hardware_unsetup();
7f59f492d   Rusty Russell   KVM: use cpumask_...
2525
2526
  out_free_0a:
  	free_cpumask_var(cpus_hardware_enabled);
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2527
  out_free_0:
edba23e51   Gleb Natapov   KVM: Return EFAUL...
2528
2529
  	if (fault_page)
  		__free_page(fault_page);
bf998156d   Huang Ying   KVM: Avoid killin...
2530
2531
  	if (hwpoison_page)
  		__free_page(hwpoison_page);
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2532
  	__free_page(bad_page);
ca45aaae1   Avi Kivity   KVM: Unset kvm_ar...
2533
  out:
f8c16bbaa   Zhang Xiantao   KVM: Portability:...
2534
  	kvm_arch_exit();
d23087847   Zhang Xiantao   KVM: Correct kvm_...
2535
  out_fail:
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2536
2537
  	return r;
  }
cb498ea2c   Zhang Xiantao   KVM: Portability:...
2538
  EXPORT_SYMBOL_GPL(kvm_init);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2539

cb498ea2c   Zhang Xiantao   KVM: Portability:...
2540
  void kvm_exit(void)
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2541
  {
0ea4ed8e9   Darrick J. Wong   KVM: Prevent kvm_...
2542
  	kvm_exit_debug();
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2543
  	misc_deregister(&kvm_dev);
c16f862d0   Rusty Russell   KVM: Use kmem cac...
2544
  	kmem_cache_destroy(kvm_vcpu_cache);
af585b921   Gleb Natapov   KVM: Halt vcpu if...
2545
  	kvm_async_pf_deinit();
fb3600cc5   Rafael J. Wysocki   KVM: Use syscore_...
2546
  	unregister_syscore_ops(&kvm_syscore_ops);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2547
  	unregister_reboot_notifier(&kvm_reboot_notifier);
59ae6c6b8   Avi Kivity   [PATCH] KVM: Host...
2548
  	unregister_cpu_notifier(&kvm_cpu_notifier);
75b7127c3   Takuya Yoshikawa   KVM: rename hardw...
2549
  	on_each_cpu(hardware_disable_nolock, NULL, 1);
e9b11c175   Zhang Xiantao   KVM: Portability:...
2550
  	kvm_arch_hardware_unsetup();
f8c16bbaa   Zhang Xiantao   KVM: Portability:...
2551
  	kvm_arch_exit();
7f59f492d   Rusty Russell   KVM: use cpumask_...
2552
  	free_cpumask_var(cpus_hardware_enabled);
bf998156d   Huang Ying   KVM: Avoid killin...
2553
  	__free_page(hwpoison_page);
cea7bb212   Izik Eidus   KVM: MMU: Make gf...
2554
  	__free_page(bad_page);
6aa8b732c   Avi Kivity   [PATCH] kvm: user...
2555
  }
cb498ea2c   Zhang Xiantao   KVM: Portability:...
2556
  EXPORT_SYMBOL_GPL(kvm_exit);