aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-05-31 08:46:04 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-16 05:05:44 -0400
commite663ee64aefc57f7eff7325142206c4ea0200be8 (patch)
treea95c5a1015914ee4101c1770039ad1457e8767c3
parent0d551bb698e1328f685ae3611c4a4a96f41bef97 (diff)
KVM: MMU: Make setting shadow ptes atomic on i386
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/Kconfig1
-rw-r--r--drivers/kvm/mmu.c14
-rw-r--r--drivers/kvm/paging_tmpl.h4
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
11config KVM 11config 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
208static 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
207static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, 217static 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);