aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/paging_tmpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/paging_tmpl.h')
-rw-r--r--drivers/kvm/paging_tmpl.h28
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index 6e013015f0a8..6f79ae87d0cf 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -52,6 +52,9 @@
52 #error Invalid PTTYPE value 52 #error Invalid PTTYPE value
53#endif 53#endif
54 54
55#define gpte_to_gfn FNAME(gpte_to_gfn)
56#define gpte_to_gfn_pde FNAME(gpte_to_gfn_pde)
57
55/* 58/*
56 * The guest_walker structure emulates the behavior of the hardware page 59 * The guest_walker structure emulates the behavior of the hardware page
57 * table walker. 60 * table walker.
@@ -65,6 +68,16 @@ struct guest_walker {
65 u32 error_code; 68 u32 error_code;
66}; 69};
67 70
71static gfn_t gpte_to_gfn(pt_element_t gpte)
72{
73 return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
74}
75
76static gfn_t gpte_to_gfn_pde(pt_element_t gpte)
77{
78 return (gpte & PT_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
79}
80
68/* 81/*
69 * Fetch a guest pte for a guest virtual address 82 * Fetch a guest pte for a guest virtual address
70 */ 83 */
@@ -96,7 +109,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
96 for (;;) { 109 for (;;) {
97 index = PT_INDEX(addr, walker->level); 110 index = PT_INDEX(addr, walker->level);
98 111
99 table_gfn = (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; 112 table_gfn = gpte_to_gfn(pte);
100 pte_gpa = table_gfn << PAGE_SHIFT; 113 pte_gpa = table_gfn << PAGE_SHIFT;
101 pte_gpa += index * sizeof(pt_element_t); 114 pte_gpa += index * sizeof(pt_element_t);
102 walker->table_gfn[walker->level - 1] = table_gfn; 115 walker->table_gfn[walker->level - 1] = table_gfn;
@@ -127,15 +140,14 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
127 } 140 }
128 141
129 if (walker->level == PT_PAGE_TABLE_LEVEL) { 142 if (walker->level == PT_PAGE_TABLE_LEVEL) {
130 walker->gfn = (pte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; 143 walker->gfn = gpte_to_gfn(pte);
131 break; 144 break;
132 } 145 }
133 146
134 if (walker->level == PT_DIRECTORY_LEVEL 147 if (walker->level == PT_DIRECTORY_LEVEL
135 && (pte & PT_PAGE_SIZE_MASK) 148 && (pte & PT_PAGE_SIZE_MASK)
136 && (PTTYPE == 64 || is_pse(vcpu))) { 149 && (PTTYPE == 64 || is_pse(vcpu))) {
137 walker->gfn = (pte & PT_DIR_BASE_ADDR_MASK) 150 walker->gfn = gpte_to_gfn_pde(pte);
138 >> PAGE_SHIFT;
139 walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL); 151 walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL);
140 break; 152 break;
141 } 153 }
@@ -296,8 +308,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
296 return; 308 return;
297 pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte); 309 pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte);
298 FNAME(set_pte)(vcpu, gpte, spte, PT_USER_MASK | PT_WRITABLE_MASK, 0, 310 FNAME(set_pte)(vcpu, gpte, spte, PT_USER_MASK | PT_WRITABLE_MASK, 0,
299 0, NULL, NULL, 311 0, NULL, NULL, gpte_to_gfn(gpte));
300 (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT);
301} 312}
302 313
303static void FNAME(set_pde)(struct kvm_vcpu *vcpu, pt_element_t gpde, 314static void FNAME(set_pde)(struct kvm_vcpu *vcpu, pt_element_t gpde,
@@ -370,8 +381,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
370 hugepage_access >>= PT_WRITABLE_SHIFT; 381 hugepage_access >>= PT_WRITABLE_SHIFT;
371 if (walker->pte & PT64_NX_MASK) 382 if (walker->pte & PT64_NX_MASK)
372 hugepage_access |= (1 << 2); 383 hugepage_access |= (1 << 2);
373 table_gfn = (walker->pte & PT_BASE_ADDR_MASK) 384 table_gfn = gpte_to_gfn(walker->pte);
374 >> PAGE_SHIFT;
375 } else { 385 } else {
376 metaphysical = 0; 386 metaphysical = 0;
377 table_gfn = walker->table_gfn[level - 2]; 387 table_gfn = walker->table_gfn[level - 2];
@@ -519,3 +529,5 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
519#undef PT_DIR_BASE_ADDR_MASK 529#undef PT_DIR_BASE_ADDR_MASK
520#undef PT_LEVEL_BITS 530#undef PT_LEVEL_BITS
521#undef PT_MAX_FULL_LEVELS 531#undef PT_MAX_FULL_LEVELS
532#undef gpte_to_gfn
533#undef gpte_to_gfn_pde