diff options
author | Avi Kivity <avi@qumranet.com> | 2007-05-31 08:46:04 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-07-16 05:05:44 -0400 |
commit | e663ee64aefc57f7eff7325142206c4ea0200be8 (patch) | |
tree | a95c5a1015914ee4101c1770039ad1457e8767c3 | |
parent | 0d551bb698e1328f685ae3611c4a4a96f41bef97 (diff) |
KVM: MMU: Make setting shadow ptes atomic on i386
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/Kconfig | 1 | ||||
-rw-r--r-- | drivers/kvm/mmu.c | 14 | ||||
-rw-r--r-- | drivers/kvm/paging_tmpl.h | 4 |
3 files changed, 15 insertions, 4 deletions
diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig index 2f661e5f0dae..33fa28a8c199 100644 --- a/drivers/kvm/Kconfig +++ b/drivers/kvm/Kconfig | |||
@@ -11,6 +11,7 @@ if VIRTUALIZATION | |||
11 | config KVM | 11 | config KVM |
12 | tristate "Kernel-based Virtual Machine (KVM) support" | 12 | tristate "Kernel-based Virtual Machine (KVM) support" |
13 | depends on X86 && EXPERIMENTAL | 13 | depends on X86 && EXPERIMENTAL |
14 | depends on X86_CMPXCHG64 || 64BIT | ||
14 | ---help--- | 15 | ---help--- |
15 | Support hosting fully virtualized guest machines using hardware | 16 | Support hosting fully virtualized guest machines using hardware |
16 | virtualization extensions. You will need a fairly recent | 17 | virtualization extensions. You will need a fairly recent |
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index 3cdbf687df25..f24b540148aa 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <asm/cmpxchg.h> | ||
25 | 26 | ||
26 | #include "vmx.h" | 27 | #include "vmx.h" |
27 | #include "kvm.h" | 28 | #include "kvm.h" |
@@ -204,6 +205,15 @@ static int is_rmap_pte(u64 pte) | |||
204 | == (PT_WRITABLE_MASK | PT_PRESENT_MASK); | 205 | == (PT_WRITABLE_MASK | PT_PRESENT_MASK); |
205 | } | 206 | } |
206 | 207 | ||
208 | static void set_shadow_pte(u64 *sptep, u64 spte) | ||
209 | { | ||
210 | #ifdef CONFIG_X86_64 | ||
211 | set_64bit((unsigned long *)sptep, spte); | ||
212 | #else | ||
213 | set_64bit((unsigned long long *)sptep, spte); | ||
214 | #endif | ||
215 | } | ||
216 | |||
207 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, | 217 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, |
208 | struct kmem_cache *base_cache, int min, | 218 | struct kmem_cache *base_cache, int min, |
209 | gfp_t gfp_flags) | 219 | gfp_t gfp_flags) |
@@ -446,7 +456,7 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) | |||
446 | rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); | 456 | rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); |
447 | rmap_remove(vcpu, spte); | 457 | rmap_remove(vcpu, spte); |
448 | kvm_arch_ops->tlb_flush(vcpu); | 458 | kvm_arch_ops->tlb_flush(vcpu); |
449 | *spte &= ~(u64)PT_WRITABLE_MASK; | 459 | set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK); |
450 | } | 460 | } |
451 | } | 461 | } |
452 | 462 | ||
@@ -699,7 +709,7 @@ static void kvm_mmu_zap_page(struct kvm_vcpu *vcpu, | |||
699 | } | 709 | } |
700 | BUG_ON(!parent_pte); | 710 | BUG_ON(!parent_pte); |
701 | kvm_mmu_put_page(vcpu, page, parent_pte); | 711 | kvm_mmu_put_page(vcpu, page, parent_pte); |
702 | *parent_pte = 0; | 712 | set_shadow_pte(parent_pte, 0); |
703 | } | 713 | } |
704 | kvm_mmu_page_unlink_children(vcpu, page); | 714 | kvm_mmu_page_unlink_children(vcpu, page); |
705 | if (!page->root_count) { | 715 | if (!page->root_count) { |
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 397a4039eaad..fabc2c9093cd 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h | |||
@@ -234,7 +234,7 @@ static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu, | |||
234 | spte |= gaddr; | 234 | spte |= gaddr; |
235 | spte |= PT_SHADOW_IO_MARK; | 235 | spte |= PT_SHADOW_IO_MARK; |
236 | spte &= ~PT_PRESENT_MASK; | 236 | spte &= ~PT_PRESENT_MASK; |
237 | *shadow_pte = spte; | 237 | set_shadow_pte(shadow_pte, spte); |
238 | return; | 238 | return; |
239 | } | 239 | } |
240 | 240 | ||
@@ -280,7 +280,7 @@ unshadowed: | |||
280 | if (access_bits & PT_WRITABLE_MASK) | 280 | if (access_bits & PT_WRITABLE_MASK) |
281 | mark_page_dirty(vcpu->kvm, gaddr >> PAGE_SHIFT); | 281 | mark_page_dirty(vcpu->kvm, gaddr >> PAGE_SHIFT); |
282 | 282 | ||
283 | *shadow_pte = spte; | 283 | set_shadow_pte(shadow_pte, spte); |
284 | page_header_update_slot(vcpu->kvm, shadow_pte, gaddr); | 284 | page_header_update_slot(vcpu->kvm, shadow_pte, gaddr); |
285 | if (!was_rmapped) | 285 | if (!was_rmapped) |
286 | rmap_add(vcpu, shadow_pte); | 286 | rmap_add(vcpu, shadow_pte); |