mirror of
https://github.com/torvalds/linux.git
synced 2024-10-24 14:10:59 +00:00
KVM: MMU: Make setting shadow ptes atomic on i386
Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
0d551bb698
commit
e663ee64ae
|
@ -11,6 +11,7 @@ if VIRTUALIZATION
|
||||||
config KVM
|
config KVM
|
||||||
tristate "Kernel-based Virtual Machine (KVM) support"
|
tristate "Kernel-based Virtual Machine (KVM) support"
|
||||||
depends on X86 && EXPERIMENTAL
|
depends on X86 && EXPERIMENTAL
|
||||||
|
depends on X86_CMPXCHG64 || 64BIT
|
||||||
---help---
|
---help---
|
||||||
Support hosting fully virtualized guest machines using hardware
|
Support hosting fully virtualized guest machines using hardware
|
||||||
virtualization extensions. You will need a fairly recent
|
virtualization extensions. You will need a fairly recent
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <asm/cmpxchg.h>
|
||||||
|
|
||||||
#include "vmx.h"
|
#include "vmx.h"
|
||||||
#include "kvm.h"
|
#include "kvm.h"
|
||||||
|
@ -204,6 +205,15 @@ static int is_rmap_pte(u64 pte)
|
||||||
== (PT_WRITABLE_MASK | PT_PRESENT_MASK);
|
== (PT_WRITABLE_MASK | PT_PRESENT_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_shadow_pte(u64 *sptep, u64 spte)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
set_64bit((unsigned long *)sptep, spte);
|
||||||
|
#else
|
||||||
|
set_64bit((unsigned long long *)sptep, spte);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
|
static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
|
||||||
struct kmem_cache *base_cache, int min,
|
struct kmem_cache *base_cache, int min,
|
||||||
gfp_t gfp_flags)
|
gfp_t gfp_flags)
|
||||||
|
@ -446,7 +456,7 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn)
|
||||||
rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
|
rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
|
||||||
rmap_remove(vcpu, spte);
|
rmap_remove(vcpu, spte);
|
||||||
kvm_arch_ops->tlb_flush(vcpu);
|
kvm_arch_ops->tlb_flush(vcpu);
|
||||||
*spte &= ~(u64)PT_WRITABLE_MASK;
|
set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +709,7 @@ static void kvm_mmu_zap_page(struct kvm_vcpu *vcpu,
|
||||||
}
|
}
|
||||||
BUG_ON(!parent_pte);
|
BUG_ON(!parent_pte);
|
||||||
kvm_mmu_put_page(vcpu, page, parent_pte);
|
kvm_mmu_put_page(vcpu, page, parent_pte);
|
||||||
*parent_pte = 0;
|
set_shadow_pte(parent_pte, 0);
|
||||||
}
|
}
|
||||||
kvm_mmu_page_unlink_children(vcpu, page);
|
kvm_mmu_page_unlink_children(vcpu, page);
|
||||||
if (!page->root_count) {
|
if (!page->root_count) {
|
||||||
|
|
|
@ -234,7 +234,7 @@ static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
|
||||||
spte |= gaddr;
|
spte |= gaddr;
|
||||||
spte |= PT_SHADOW_IO_MARK;
|
spte |= PT_SHADOW_IO_MARK;
|
||||||
spte &= ~PT_PRESENT_MASK;
|
spte &= ~PT_PRESENT_MASK;
|
||||||
*shadow_pte = spte;
|
set_shadow_pte(shadow_pte, spte);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ unshadowed:
|
||||||
if (access_bits & PT_WRITABLE_MASK)
|
if (access_bits & PT_WRITABLE_MASK)
|
||||||
mark_page_dirty(vcpu->kvm, gaddr >> PAGE_SHIFT);
|
mark_page_dirty(vcpu->kvm, gaddr >> PAGE_SHIFT);
|
||||||
|
|
||||||
*shadow_pte = spte;
|
set_shadow_pte(shadow_pte, spte);
|
||||||
page_header_update_slot(vcpu->kvm, shadow_pte, gaddr);
|
page_header_update_slot(vcpu->kvm, shadow_pte, gaddr);
|
||||||
if (!was_rmapped)
|
if (!was_rmapped)
|
||||||
rmap_add(vcpu, shadow_pte);
|
rmap_add(vcpu, shadow_pte);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user