aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2009-05-12 17:55:45 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:55 -0400
commit8986ecc0ef58c96eec48d8502c048f3ab67fd8e2 (patch)
treeb2682f02bcb1e437e62463a17d7adc95a6735b60
parentb43b1901ad282aeb74161837fb403927102687a1 (diff)
KVM: x86: check for cr3 validity in mmu_alloc_roots
Verify the cr3 address stored in vcpu->arch.cr3 points to an existant memslot. If not, inject a triple fault. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/kvm/mmu.c27
-rw-r--r--arch/x86/kvm/x86.c1
2 files changed, 24 insertions, 4 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 3ce60ad1fe37..5c3d6e81a7dc 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1912,7 +1912,19 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
1912 vcpu->arch.mmu.root_hpa = INVALID_PAGE; 1912 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
1913} 1913}
1914 1914
1915static void mmu_alloc_roots(struct kvm_vcpu *vcpu) 1915static int mmu_check_root(struct kvm_vcpu *vcpu, gfn_t root_gfn)
1916{
1917 int ret = 0;
1918
1919 if (!kvm_is_visible_gfn(vcpu->kvm, root_gfn)) {
1920 set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
1921 ret = 1;
1922 }
1923
1924 return ret;
1925}
1926
1927static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
1916{ 1928{
1917 int i; 1929 int i;
1918 gfn_t root_gfn; 1930 gfn_t root_gfn;
@@ -1927,13 +1939,15 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
1927 ASSERT(!VALID_PAGE(root)); 1939 ASSERT(!VALID_PAGE(root));
1928 if (tdp_enabled) 1940 if (tdp_enabled)
1929 direct = 1; 1941 direct = 1;
1942 if (mmu_check_root(vcpu, root_gfn))
1943 return 1;
1930 sp = kvm_mmu_get_page(vcpu, root_gfn, 0, 1944 sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
1931 PT64_ROOT_LEVEL, direct, 1945 PT64_ROOT_LEVEL, direct,
1932 ACC_ALL, NULL); 1946 ACC_ALL, NULL);
1933 root = __pa(sp->spt); 1947 root = __pa(sp->spt);
1934 ++sp->root_count; 1948 ++sp->root_count;
1935 vcpu->arch.mmu.root_hpa = root; 1949 vcpu->arch.mmu.root_hpa = root;
1936 return; 1950 return 0;
1937 } 1951 }
1938 direct = !is_paging(vcpu); 1952 direct = !is_paging(vcpu);
1939 if (tdp_enabled) 1953 if (tdp_enabled)
@@ -1950,6 +1964,8 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
1950 root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT; 1964 root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT;
1951 } else if (vcpu->arch.mmu.root_level == 0) 1965 } else if (vcpu->arch.mmu.root_level == 0)
1952 root_gfn = 0; 1966 root_gfn = 0;
1967 if (mmu_check_root(vcpu, root_gfn))
1968 return 1;
1953 sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, 1969 sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
1954 PT32_ROOT_LEVEL, direct, 1970 PT32_ROOT_LEVEL, direct,
1955 ACC_ALL, NULL); 1971 ACC_ALL, NULL);
@@ -1958,6 +1974,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
1958 vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK; 1974 vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
1959 } 1975 }
1960 vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root); 1976 vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
1977 return 0;
1961} 1978}
1962 1979
1963static void mmu_sync_roots(struct kvm_vcpu *vcpu) 1980static void mmu_sync_roots(struct kvm_vcpu *vcpu)
@@ -1976,7 +1993,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
1976 for (i = 0; i < 4; ++i) { 1993 for (i = 0; i < 4; ++i) {
1977 hpa_t root = vcpu->arch.mmu.pae_root[i]; 1994 hpa_t root = vcpu->arch.mmu.pae_root[i];
1978 1995
1979 if (root) { 1996 if (root && VALID_PAGE(root)) {
1980 root &= PT64_BASE_ADDR_MASK; 1997 root &= PT64_BASE_ADDR_MASK;
1981 sp = page_header(root); 1998 sp = page_header(root);
1982 mmu_sync_children(vcpu, sp); 1999 mmu_sync_children(vcpu, sp);
@@ -2311,9 +2328,11 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
2311 goto out; 2328 goto out;
2312 spin_lock(&vcpu->kvm->mmu_lock); 2329 spin_lock(&vcpu->kvm->mmu_lock);
2313 kvm_mmu_free_some_pages(vcpu); 2330 kvm_mmu_free_some_pages(vcpu);
2314 mmu_alloc_roots(vcpu); 2331 r = mmu_alloc_roots(vcpu);
2315 mmu_sync_roots(vcpu); 2332 mmu_sync_roots(vcpu);
2316 spin_unlock(&vcpu->kvm->mmu_lock); 2333 spin_unlock(&vcpu->kvm->mmu_lock);
2334 if (r)
2335 goto out;
2317 kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa); 2336 kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
2318 kvm_mmu_flush_tlb(vcpu); 2337 kvm_mmu_flush_tlb(vcpu);
2319out: 2338out:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d2a4eca26181..3244437e67b3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4568,6 +4568,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
4568void kvm_arch_flush_shadow(struct kvm *kvm) 4568void kvm_arch_flush_shadow(struct kvm *kvm)
4569{ 4569{
4570 kvm_mmu_zap_all(kvm); 4570 kvm_mmu_zap_all(kvm);
4571 kvm_reload_remote_mmus(kvm);
4571} 4572}
4572 4573
4573int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) 4574int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)