aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h9
-rw-r--r--drivers/kvm/kvm_main.c33
-rw-r--r--drivers/kvm/paging_tmpl.h2
3 files changed, 25 insertions, 19 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 7117c3b3cca..983c33f3837 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -19,12 +19,9 @@
19#include <linux/kvm.h> 19#include <linux/kvm.h>
20#include <linux/kvm_para.h> 20#include <linux/kvm_para.h>
21 21
22#define CR3_WPT_MASK (1ULL << 3) 22#define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
23#define CR3_PCD_MASK (1ULL << 4) 23#define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD))
24 24#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS|0xFFFFFF0000000000ULL)
25#define CR3_RESEVED_BITS 0x07ULL
26#define CR3_L_MODE_RESEVED_BITS (~((1ULL << 40) - 1) | 0x0fe7ULL)
27#define CR3_FLAGS_MASK ((1ULL << 5) - 1)
28 25
29#define CR4_VME_MASK (1ULL << 0) 26#define CR4_VME_MASK (1ULL << 0)
30#define CR4_PSE_MASK (1ULL << 4) 27#define CR4_PSE_MASK (1ULL << 4)
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5d8febe580d..34a571dee51 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -571,23 +571,32 @@ EXPORT_SYMBOL_GPL(set_cr4);
571void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) 571void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
572{ 572{
573 if (is_long_mode(vcpu)) { 573 if (is_long_mode(vcpu)) {
574 if (cr3 & CR3_L_MODE_RESEVED_BITS) { 574 if (cr3 & CR3_L_MODE_RESERVED_BITS) {
575 printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); 575 printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
576 inject_gp(vcpu); 576 inject_gp(vcpu);
577 return; 577 return;
578 } 578 }
579 } else { 579 } else {
580 if (cr3 & CR3_RESEVED_BITS) { 580 if (is_pae(vcpu)) {
581 printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); 581 if (cr3 & CR3_PAE_RESERVED_BITS) {
582 inject_gp(vcpu); 582 printk(KERN_DEBUG
583 return; 583 "set_cr3: #GP, reserved bits\n");
584 } 584 inject_gp(vcpu);
585 if (is_paging(vcpu) && is_pae(vcpu) && 585 return;
586 !load_pdptrs(vcpu, cr3)) { 586 }
587 printk(KERN_DEBUG "set_cr3: #GP, pdptrs " 587 if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
588 "reserved bits\n"); 588 printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
589 inject_gp(vcpu); 589 "reserved bits\n");
590 return; 590 inject_gp(vcpu);
591 return;
592 }
593 } else {
594 if (cr3 & CR3_NONPAE_RESERVED_BITS) {
595 printk(KERN_DEBUG
596 "set_cr3: #GP, reserved bits\n");
597 inject_gp(vcpu);
598 return;
599 }
591 } 600 }
592 } 601 }
593 602
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index 4b5391c717f..01901ec3fe8 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -99,7 +99,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
99 walker->table = kmap_atomic(pfn_to_page(hpa >> PAGE_SHIFT), KM_USER0); 99 walker->table = kmap_atomic(pfn_to_page(hpa >> PAGE_SHIFT), KM_USER0);
100 100
101 ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) || 101 ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
102 (vcpu->cr3 & ~(PAGE_MASK | CR3_FLAGS_MASK)) == 0); 102 (vcpu->cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
103 103
104 walker->inherited_ar = PT_USER_MASK | PT_WRITABLE_MASK; 104 walker->inherited_ar = PT_USER_MASK | PT_WRITABLE_MASK;
105 105